5#include <fuchsia/accessibility/semantics/cpp/fidl.h>
6#include <fuchsia/buildinfo/cpp/fidl.h>
7#include <fuchsia/component/cpp/fidl.h>
8#include <fuchsia/fonts/cpp/fidl.h>
9#include <fuchsia/input/report/cpp/fidl.h>
10#include <fuchsia/kernel/cpp/fidl.h>
11#include <fuchsia/logger/cpp/fidl.h>
12#include <fuchsia/memorypressure/cpp/fidl.h>
13#include <fuchsia/metrics/cpp/fidl.h>
14#include <fuchsia/net/interfaces/cpp/fidl.h>
15#include <fuchsia/tracing/provider/cpp/fidl.h>
16#include <fuchsia/ui/app/cpp/fidl.h>
17#include <fuchsia/ui/display/singleton/cpp/fidl.h>
18#include <fuchsia/ui/input/cpp/fidl.h>
19#include <fuchsia/ui/test/input/cpp/fidl.h>
20#include <fuchsia/web/cpp/fidl.h>
21#include <lib/async/cpp/task.h>
22#include <lib/fidl/cpp/binding_set.h>
23#include <lib/sys/component/cpp/testing/realm_builder.h>
24#include <lib/sys/component/cpp/testing/realm_builder_types.h>
25#include <zircon/status.h>
26#include <zircon/types.h>
27#include <zircon/utc.h>
40#include <gtest/gtest.h>
42#include "flutter/fml/logging.h"
43#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h"
44#include "lib/fidl/cpp/interface_ptr.h"
49using component_testing::ChildRef;
50using component_testing::ConfigValue;
51using component_testing::LocalComponentImpl;
52using component_testing::ParentRef;
53using component_testing::Protocol;
54using component_testing::Realm;
55using component_testing::Route;
58using RealmBuilder = component_testing::RealmBuilder;
61using ChildName = std::string;
64using LegacyUrl = std::string;
72constexpr int64_t kClickToDragThreshold = 16.0;
74constexpr auto kMouseInputListener =
"mouse_input_listener";
75constexpr auto kMouseInputListenerRef = ChildRef{kMouseInputListener};
76constexpr auto kMouseInputView =
"mouse-input-view";
77constexpr auto kMouseInputViewRef = ChildRef{kMouseInputView};
78constexpr auto kMouseInputViewUrl =
79 "fuchsia-pkg://fuchsia.com/mouse-input-view#meta/mouse-input-view.cm";
88std::vector<T>
merge(std::initializer_list<std::vector<T>> vecs) {
97 const std::vector<fuchsia::ui::test::input::MouseButton>& buttons) {
99 for (
const auto& button : buttons) {
100 result |= (0x1 >> button);
108class MouseInputListenerServer
109 :
public fuchsia::ui::test::input::MouseInputListener,
110 public LocalComponentImpl {
112 explicit MouseInputListenerServer(async_dispatcher_t* dispatcher)
113 : dispatcher_(dispatcher) {}
115 void ReportMouseInput(
116 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest
118 FML_LOG(INFO) <<
"Received MouseInput event";
119 events_.push(std::move(request));
125 void OnStart()
override {
126 FML_LOG(INFO) <<
"Starting MouseInputServer";
127 ASSERT_EQ(ZX_OK, outgoing()->AddPublicService(
128 fidl::InterfaceRequestHandler<
129 fuchsia::ui::test::input::MouseInputListener>(
130 [
this](
auto request) {
131 bindings_.AddBinding(
this, std::move(request),
136 size_t SizeOfEvents()
const {
return events_.size(); }
138 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest
140 auto e = std::move(events_.front());
145 const fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
147 return events_.back();
150 void ClearEvents() { events_ = {}; }
154 async_dispatcher_t* dispatcher_ =
nullptr;
155 fidl::BindingSet<fuchsia::ui::test::input::MouseInputListener> bindings_;
157 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest>
161class MouseInputTest :
public PortableUITest,
162 public ::testing::Test,
163 public ::testing::WithParamInterface<std::string> {
165 void SetUp()
override {
166 PortableUITest::SetUp();
173 <<
"Waiting for display info from fuchsia.ui.display.singleton.Info";
174 fuchsia::ui::display::singleton::InfoPtr display_info =
177 .Connect<fuchsia::ui::display::singleton::Info>();
178 display_info->GetMetrics(
179 [
this](fuchsia::ui::display::singleton::Metrics metrics) {
180 display_width_ = metrics.extent_in_px().width;
181 display_height_ = metrics.extent_in_px().height;
182 FML_LOG(INFO) <<
"Got display_width = " << display_width_
183 <<
" and display_height = " << display_height_;
186 [
this] {
return display_width_ != 0 && display_height_ != 0; });
189 void TearDown()
override {
191 ASSERT_EQ(mouse_input_listener_->SizeOfEvents(), 0u);
194 MouseInputListenerServer* mouse_input_listener() {
195 return mouse_input_listener_;
201 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
205 std::vector<fuchsia::ui::test::input::MouseButton> expected_buttons,
206 const fuchsia::ui::test::input::MouseEventPhase expected_phase,
207 const std::string& component_name) {
208 FML_LOG(INFO) <<
"Client received mouse change at ("
209 << pointer_data.local_x() <<
", " << pointer_data.local_y()
210 <<
") with buttons " << ButtonsToInt(pointer_data.buttons())
212 FML_LOG(INFO) <<
"Expected mouse change is at approximately (" << expected_x
213 <<
", " << expected_y <<
") with buttons "
214 << ButtonsToInt(expected_buttons) <<
".";
221 EXPECT_NEAR(pointer_data.local_x(), expected_x, 1);
222 EXPECT_NEAR(pointer_data.local_y(), expected_y, 1);
223 EXPECT_EQ(pointer_data.buttons(), expected_buttons);
224 EXPECT_EQ(pointer_data.phase(), expected_phase);
225 EXPECT_EQ(pointer_data.component_name(), component_name);
228 void VerifyEventLocationOnTheRightOfExpectation(
229 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
231 double expected_x_min,
233 std::vector<fuchsia::ui::test::input::MouseButton> expected_buttons,
234 const fuchsia::ui::test::input::MouseEventPhase expected_phase,
235 const std::string& component_name) {
236 FML_LOG(INFO) <<
"Client received mouse change at ("
237 << pointer_data.local_x() <<
", " << pointer_data.local_y()
238 <<
") with buttons " << ButtonsToInt(pointer_data.buttons())
240 FML_LOG(INFO) <<
"Expected mouse change is at approximately (>"
241 << expected_x_min <<
", " << expected_y <<
") with buttons "
242 << ButtonsToInt(expected_buttons) <<
".";
244 EXPECT_GT(pointer_data.local_x(), expected_x_min);
245 EXPECT_NEAR(pointer_data.local_y(), expected_y, 1);
246 EXPECT_EQ(pointer_data.buttons(), expected_buttons);
247 EXPECT_EQ(pointer_data.phase(), expected_phase);
248 EXPECT_EQ(pointer_data.component_name(), component_name);
252 uint32_t display_width()
const {
return display_width_; }
253 uint32_t display_height()
const {
return display_height_; }
256 void ExtendRealm()
override {
257 FML_LOG(INFO) <<
"Extending realm";
261 auto mouse_input_listener =
262 std::make_unique<MouseInputListenerServer>(dispatcher());
263 mouse_input_listener_ = mouse_input_listener.get();
264 realm_builder()->AddLocalChild(
266 [mouse_input_listener = std::move(mouse_input_listener)]()
mutable {
267 return std::move(mouse_input_listener);
270 realm_builder()->AddChild(kMouseInputView, kMouseInputViewUrl,
271 component_testing::ChildOptions{
272 .environment = kFlutterRunnerEnvironment,
275 realm_builder()->AddRoute(
276 Route{.capabilities = {Protocol{
277 fuchsia::ui::test::input::MouseInputListener::Name_}},
278 .source = kMouseInputListenerRef,
279 .targets = {kFlutterJitRunnerRef, kMouseInputViewRef}});
281 realm_builder()->AddRoute(
282 Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
283 .source = kMouseInputViewRef,
284 .targets = {ParentRef()}});
287 ParamType GetTestUIStackUrl()
override {
return GetParam(); };
289 MouseInputListenerServer* mouse_input_listener_;
291 uint32_t display_width_ = 0;
292 uint32_t display_height_ = 0;
300 MouseInputTestParameterized,
303 "fuchsia-pkg://fuchsia.com/flatland-scene-manager-test-ui-stack#meta/"
304 "test-ui-stack.cm"));
306TEST_P(MouseInputTest, DISABLED_FlutterMouseMove) {
309 SimulateMouseEvent( {}, 1,
312 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
314 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
316 auto e = mouse_input_listener()->PopEvent();
321 static_cast<double>(display_width()) / 2.f + 1,
322 static_cast<double>(display_height()) / 2.f + 2,
328TEST_P(MouseInputTest, DISABLED_FlutterMouseDown) {
332 {fuchsia::ui::test::input::MouseButton::FIRST},
335 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 3; });
337 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
339 auto event_add = mouse_input_listener()->PopEvent();
340 auto event_down = mouse_input_listener()->PopEvent();
341 auto event_noop_move = mouse_input_listener()->PopEvent();
345 VerifyEvent(event_add,
346 static_cast<double>(display_width()) / 2.f,
347 static_cast<double>(display_height()) / 2.f,
355 static_cast<double>(display_width()) / 2.f,
356 static_cast<double>(display_height()) / 2.f,
357 {fuchsia::ui::test::input::MouseButton::FIRST},
358 fuchsia::ui::test::input::MouseEventPhase::DOWN,
364 static_cast<double>(display_width()) / 2.f,
365 static_cast<double>(display_height()) / 2.f,
366 {fuchsia::ui::test::input::MouseButton::FIRST},
371TEST_P(MouseInputTest, DISABLED_FlutterMouseDownUp) {
375 {fuchsia::ui::test::input::MouseButton::FIRST},
378 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 3; });
380 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
382 auto event_add = mouse_input_listener()->PopEvent();
383 auto event_down = mouse_input_listener()->PopEvent();
384 auto event_noop_move = mouse_input_listener()->PopEvent();
388 VerifyEvent(event_add,
389 static_cast<double>(display_width()) / 2.f,
390 static_cast<double>(display_height()) / 2.f,
398 static_cast<double>(display_width()) / 2.f,
399 static_cast<double>(display_height()) / 2.f,
400 {fuchsia::ui::test::input::MouseButton::FIRST},
401 fuchsia::ui::test::input::MouseEventPhase::DOWN,
407 static_cast<double>(display_width()) / 2.f,
408 static_cast<double>(display_height()) / 2.f,
409 {fuchsia::ui::test::input::MouseButton::FIRST},
413 SimulateMouseEvent( {}, 0,
416 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
418 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
420 auto event_up = mouse_input_listener()->PopEvent();
421 VerifyEvent(event_up,
422 static_cast<double>(display_width()) / 2.f,
423 static_cast<double>(display_height()) / 2.f,
425 fuchsia::ui::test::input::MouseEventPhase::UP,
429TEST_P(MouseInputTest, DISABLED_FlutterMouseDownMoveUp) {
433 {fuchsia::ui::test::input::MouseButton::FIRST},
436 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 3; });
438 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
440 auto event_add = mouse_input_listener()->PopEvent();
441 auto event_down = mouse_input_listener()->PopEvent();
442 auto event_noop_move = mouse_input_listener()->PopEvent();
446 VerifyEvent(event_add,
447 static_cast<double>(display_width()) / 2.f,
448 static_cast<double>(display_height()) / 2.f,
456 static_cast<double>(display_width()) / 2.f,
457 static_cast<double>(display_height()) / 2.f,
458 {fuchsia::ui::test::input::MouseButton::FIRST},
459 fuchsia::ui::test::input::MouseEventPhase::DOWN,
465 static_cast<double>(display_width()) / 2.f,
466 static_cast<double>(display_height()) / 2.f,
467 {fuchsia::ui::test::input::MouseButton::FIRST},
472 {fuchsia::ui::test::input::MouseButton::FIRST},
473 kClickToDragThreshold, 0);
475 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
477 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
479 auto event_move = mouse_input_listener()->PopEvent();
481 VerifyEventLocationOnTheRightOfExpectation(
483 static_cast<double>(display_width()) / 2.f + 1,
484 static_cast<double>(display_height()) / 2.f,
485 {fuchsia::ui::test::input::MouseButton::FIRST},
489 SimulateMouseEvent( {}, 0,
492 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
494 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
496 auto event_up = mouse_input_listener()->PopEvent();
498 VerifyEventLocationOnTheRightOfExpectation(
500 static_cast<double>(display_width()) / 2.f + 1,
501 static_cast<double>(display_height()) / 2.f,
503 fuchsia::ui::test::input::MouseEventPhase::UP,
513TEST_P(MouseInputTest, DISABLED_FlutterMouseWheelIssue103098) {
516 SimulateMouseScroll( {}, 1,
520 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 3; });
522 double initial_x =
static_cast<double>(display_width()) / 2.f;
523 double initial_y =
static_cast<double>(display_height()) / 2.f;
525 auto event_1 = mouse_input_listener()->PopEvent();
526 EXPECT_NEAR(event_1.local_x(), initial_x, 1);
527 EXPECT_NEAR(event_1.local_y(), initial_y, 1);
529 EXPECT_GT(event_1.wheel_x_physical_pixel(), 0);
530 EXPECT_EQ(event_1.wheel_y_physical_pixel(), 0);
533 auto event_2 = mouse_input_listener()->PopEvent();
539 fuchsia::ui::test::input::MouseEventPhase::HOVER,
542 EXPECT_GT(event_2.wheel_x_physical_pixel(), 0);
543 EXPECT_EQ(event_2.wheel_y_physical_pixel(), 0);
545 auto event_3 = mouse_input_listener()->PopEvent();
551 fuchsia::ui::test::input::MouseEventPhase::HOVER,
554 EXPECT_GT(event_3.wheel_x_physical_pixel(), 0);
555 EXPECT_EQ(event_3.wheel_y_physical_pixel(), 0);
558TEST_P(MouseInputTest, DISABLED_FlutterMouseWheel) {
561 double initial_x =
static_cast<double>(display_width()) / 2.f + 1;
562 double initial_y =
static_cast<double>(display_height()) / 2.f + 2;
565 SimulateMouseEvent( {},
568 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
570 auto event_add = mouse_input_listener()->PopEvent();
571 VerifyEvent(event_add,
578 SimulateMouseScroll( {}, 1,
581 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
583 auto event_wheel_h = mouse_input_listener()->PopEvent();
590 fuchsia::ui::test::input::MouseEventPhase::HOVER,
593 EXPECT_GT(event_wheel_h.wheel_x_physical_pixel(), 0);
594 EXPECT_EQ(event_wheel_h.wheel_y_physical_pixel(), 0);
596 SimulateMouseScroll( {}, 0,
599 [
this] {
return this->mouse_input_listener()->SizeOfEvents() == 1; });
601 auto event_wheel_v = mouse_input_listener()->PopEvent();
608 fuchsia::ui::test::input::MouseEventPhase::HOVER,
611 EXPECT_LT(event_wheel_v.wheel_y_physical_pixel(), 0);
612 EXPECT_EQ(event_wheel_v.wheel_x_physical_pixel(), 0);
static void merge(const uint8_t *SK_RESTRICT row, int rowN, const SkAlpha *SK_RESTRICT srcAA, const int16_t *SK_RESTRICT srcRuns, SkAlpha *SK_RESTRICT dstAA, int16_t *SK_RESTRICT dstRuns, int width)
#define FML_LOG(severity)
INSTANTIATE_TEST_SUITE_P(EmbedderTestGlVk, EmbedderTestMultiBackend, ::testing::Values(EmbedderTestContextType::kOpenGLContext, EmbedderTestContextType::kVulkanContext))
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)