Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
mouse-input-test.cc
Go to the documentation of this file.
1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
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/fidl/cpp/interface_ptr.h>
24#include <lib/sys/component/cpp/testing/realm_builder.h>
25#include <lib/sys/component/cpp/testing/realm_builder_types.h>
26#include <zircon/status.h>
27#include <zircon/types.h>
28#include <zircon/utc.h>
29
30#include <cstddef>
31#include <cstdint>
32#include <iostream>
33#include <memory>
34#include <optional>
35#include <queue>
36#include <string>
37#include <type_traits>
38#include <utility>
39#include <vector>
40
41#include <gtest/gtest.h>
42
43#include "flutter/fml/logging.h"
45
47namespace {
48// Types imported for the realm_builder library.
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;
56
58using RealmBuilder = component_testing::RealmBuilder;
59
60// Alias for Component child name as provided to Realm Builder.
61using ChildName = std::string;
62
63// Alias for Component Legacy URL as provided to Realm Builder.
64using LegacyUrl = std::string;
65
66// Maximum pointer movement during a clickpad press for the gesture to
67// be guaranteed to be interpreted as a click. For movement greater than
68// this value, upper layers may, e.g., interpret the gesture as a drag.
69//
70// This value corresponds to the one used to instantiate the ClickDragHandler
71// registered by Input Pipeline in Scene Manager.
72constexpr int64_t kClickToDragThreshold = 16.0;
73
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 = "mouse-input-view#meta/mouse-input-view.cm";
79
80struct Position {
81 double x = 0.0;
82 double y = 0.0;
83};
84
85// Combines all vectors in `vecs` into one.
86template <typename T>
87std::vector<T> merge(std::initializer_list<std::vector<T>> vecs) {
88 std::vector<T> result;
89 for (auto v : vecs) {
90 result.insert(result.end(), v.begin(), v.end());
91 }
92 return result;
93}
94
95int ButtonsToInt(
96 const std::vector<fuchsia::ui::test::input::MouseButton>& buttons) {
97 int result = 0;
98 for (const auto& button : buttons) {
99 result |= (0x1 >> button);
100 }
101
102 return result;
103}
104
105// `MouseInputListener` is a local test protocol that our test apps use to let
106// us know what position and button press state the mouse cursor has.
107class MouseInputListenerServer
108 : public fuchsia::ui::test::input::MouseInputListener,
109 public LocalComponentImpl {
110 public:
111 explicit MouseInputListenerServer(async_dispatcher_t* dispatcher)
112 : dispatcher_(dispatcher) {}
113
114 void ReportMouseInput(
115 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest
116 request) override {
117 FML_LOG(INFO) << "Received MouseInput event";
118 events_.push(std::move(request));
119 }
120
121 // |MockComponent::OnStart|
122 // When the component framework requests for this component to start, this
123 // method will be invoked by the realm_builder library.
124 void OnStart() override {
125 FML_LOG(INFO) << "Starting MouseInputServer";
126 ASSERT_EQ(ZX_OK, outgoing()->AddPublicService(
127 fidl::InterfaceRequestHandler<
128 fuchsia::ui::test::input::MouseInputListener>(
129 [this](auto request) {
130 bindings_.AddBinding(this, std::move(request),
131 dispatcher_);
132 })));
133 }
134
135 size_t SizeOfEvents() const { return events_.size(); }
136
137 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest
138 PopEvent() {
139 auto e = std::move(events_.front());
140 events_.pop();
141 return e;
142 }
143
144 const fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
145 LastEvent() const {
146 return events_.back();
147 }
148
149 void ClearEvents() { events_ = {}; }
150
151 private:
152 // Not owned.
153 async_dispatcher_t* dispatcher_ = nullptr;
154 fidl::BindingSet<fuchsia::ui::test::input::MouseInputListener> bindings_;
155 std::queue<
156 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest>
157 events_;
158};
159
160class MouseInputTest : public PortableUITest,
161 public ::testing::Test,
162 public ::testing::WithParamInterface<std::string> {
163 protected:
164 void SetUp() override {
165 PortableUITest::SetUp();
166
167 // Register fake mouse device.
168 RegisterMouse();
169
170 // Get the display dimensions.
171 FML_LOG(INFO)
172 << "Waiting for display info from fuchsia.ui.display.singleton.Info";
173 fuchsia::ui::display::singleton::InfoPtr display_info =
174 realm_root()
175 ->component()
176 .Connect<fuchsia::ui::display::singleton::Info>();
177 display_info->GetMetrics(
178 [this](fuchsia::ui::display::singleton::Metrics metrics) {
179 display_width_ = metrics.extent_in_px().width;
180 display_height_ = metrics.extent_in_px().height;
181 FML_LOG(INFO) << "Got display_width = " << display_width_
182 << " and display_height = " << display_height_;
183 });
184 RunLoopUntil(
185 [this] { return display_width_ != 0 && display_height_ != 0; });
186 }
187
188 void TearDown() override {
189 // at the end of test, ensure event queue is empty.
190 ASSERT_EQ(mouse_input_listener_->SizeOfEvents(), 0u);
191 }
192
193 MouseInputListenerServer* mouse_input_listener() {
194 return mouse_input_listener_;
195 }
196
197 // Helper method for checking the test.mouse.MouseInputListener response from
198 // the client app.
199 void VerifyEvent(
200 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
201 pointer_data,
202 double expected_x,
203 double expected_y,
204 std::vector<fuchsia::ui::test::input::MouseButton> expected_buttons,
205 const fuchsia::ui::test::input::MouseEventPhase expected_phase,
206 const std::string& component_name) {
207 FML_LOG(INFO) << "Client received mouse change at ("
208 << pointer_data.local_x() << ", " << pointer_data.local_y()
209 << ") with buttons " << ButtonsToInt(pointer_data.buttons())
210 << ".";
211 FML_LOG(INFO) << "Expected mouse change is at approximately (" << expected_x
212 << ", " << expected_y << ") with buttons "
213 << ButtonsToInt(expected_buttons) << ".";
214
215 // Allow for minor rounding differences in coordinates.
216 // Note: These approximations don't account for
217 // `PointerMotionDisplayScaleHandler` or `PointerMotionSensorScaleHandler`.
218 // We will need to do so in order to validate larger motion or different
219 // sized displays.
220 EXPECT_NEAR(pointer_data.local_x(), expected_x, 1);
221 EXPECT_NEAR(pointer_data.local_y(), expected_y, 1);
222 EXPECT_EQ(pointer_data.buttons(), expected_buttons);
223 EXPECT_EQ(pointer_data.phase(), expected_phase);
224 EXPECT_EQ(pointer_data.component_name(), component_name);
225 }
226
227 void VerifyEventLocationOnTheRightOfExpectation(
228 fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest&
229 pointer_data,
230 double expected_x_min,
231 double expected_y,
232 std::vector<fuchsia::ui::test::input::MouseButton> expected_buttons,
233 const fuchsia::ui::test::input::MouseEventPhase expected_phase,
234 const std::string& component_name) {
235 FML_LOG(INFO) << "Client received mouse change at ("
236 << pointer_data.local_x() << ", " << pointer_data.local_y()
237 << ") with buttons " << ButtonsToInt(pointer_data.buttons())
238 << ".";
239 FML_LOG(INFO) << "Expected mouse change is at approximately (>"
240 << expected_x_min << ", " << expected_y << ") with buttons "
241 << ButtonsToInt(expected_buttons) << ".";
242
243 EXPECT_GT(pointer_data.local_x(), expected_x_min);
244 EXPECT_NEAR(pointer_data.local_y(), expected_y, 1);
245 EXPECT_EQ(pointer_data.buttons(), expected_buttons);
246 EXPECT_EQ(pointer_data.phase(), expected_phase);
247 EXPECT_EQ(pointer_data.component_name(), component_name);
248 }
249
250 // Guaranteed to be initialized after SetUp().
251 uint32_t display_width() const { return display_width_; }
252 uint32_t display_height() const { return display_height_; }
253
254 private:
255 void ExtendRealm() override {
256 FML_LOG(INFO) << "Extending realm";
257
258 // Key part of service setup: have this test component vend the
259 // |MouseInputListener| service in the constructed realm.
260 auto mouse_input_listener =
261 std::make_unique<MouseInputListenerServer>(dispatcher());
262 mouse_input_listener_ = mouse_input_listener.get();
263 realm_builder()->AddLocalChild(
264 kMouseInputListener,
265 [mouse_input_listener = std::move(mouse_input_listener)]() mutable {
266 return std::move(mouse_input_listener);
267 });
268
269 realm_builder()->AddChild(kMouseInputView, kMouseInputViewUrl,
270 component_testing::ChildOptions{
271 .environment = kFlutterRunnerEnvironment,
272 });
273
274 realm_builder()->AddRoute(
275 Route{.capabilities = {Protocol{
276 fuchsia::ui::test::input::MouseInputListener::Name_}},
277 .source = kMouseInputListenerRef,
278 .targets = {kFlutterJitRunnerRef, kMouseInputViewRef}});
279
280 realm_builder()->AddRoute(
281 Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
282 .source = kMouseInputViewRef,
283 .targets = {ParentRef()}});
284 }
285
286 ParamType GetTestUIStackUrl() override { return GetParam(); };
287
288 MouseInputListenerServer* mouse_input_listener_;
289
290 uint32_t display_width_ = 0;
291 uint32_t display_height_ = 0;
292};
293
294// Makes use of gtest's parameterized testing, allowing us
295// to test different combinations of test-ui-stack + runners. Currently, there
296// is just one combination. Documentation:
297// http://go/gunitadvanced#value-parameterized-tests
299 MouseInputTestParameterized,
300 MouseInputTest,
301 ::testing::Values(
302 "fuchsia-pkg://fuchsia.com/flatland-scene-manager-test-ui-stack#meta/"
303 "test-ui-stack.cm"));
304
305TEST_P(MouseInputTest, DISABLED_FlutterMouseMove) {
306 LaunchClient();
307
308 SimulateMouseEvent(/* pressed_buttons = */ {}, /* movement_x = */ 1,
309 /* movement_y = */ 2);
310 RunLoopUntil(
311 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
312
313 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
314
315 auto e = mouse_input_listener()->PopEvent();
316
317 // If the first mouse event is cursor movement, Flutter first sends an ADD
318 // event with updated location.
319 VerifyEvent(e,
320 /*expected_x=*/static_cast<double>(display_width()) / 2.f + 1,
321 /*expected_y=*/static_cast<double>(display_height()) / 2.f + 2,
322 /*expected_buttons=*/{},
323 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::ADD,
324 /*component_name=*/"mouse-input-view");
325}
326
327TEST_P(MouseInputTest, DISABLED_FlutterMouseDown) {
328 LaunchClient();
329
330 SimulateMouseEvent(
331 /* pressed_buttons = */ {fuchsia::ui::test::input::MouseButton::FIRST},
332 /* movement_x = */ 0, /* movement_y = */ 0);
333 RunLoopUntil(
334 [this] { return this->mouse_input_listener()->SizeOfEvents() == 3; });
335
336 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
337
338 auto event_add = mouse_input_listener()->PopEvent();
339 auto event_down = mouse_input_listener()->PopEvent();
340 auto event_noop_move = mouse_input_listener()->PopEvent();
341
342 // If the first mouse event is a button press, Flutter first sends an ADD
343 // event with no buttons.
344 VerifyEvent(event_add,
345 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
346 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
347 /*expected_buttons=*/{},
348 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::ADD,
349 /*component_name=*/"mouse-input-view");
350
351 // Then Flutter sends a DOWN pointer event with the buttons we care about.
352 VerifyEvent(
353 event_down,
354 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
355 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
356 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
357 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::DOWN,
358 /*component_name=*/"mouse-input-view");
359
360 // Then Flutter sends a MOVE pointer event with no new information.
361 VerifyEvent(
362 event_noop_move,
363 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
364 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
365 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
366 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::MOVE,
367 /*component_name=*/"mouse-input-view");
368}
369
370TEST_P(MouseInputTest, DISABLED_FlutterMouseDownUp) {
371 LaunchClient();
372
373 SimulateMouseEvent(
374 /* pressed_buttons = */ {fuchsia::ui::test::input::MouseButton::FIRST},
375 /* movement_x = */ 0, /* movement_y = */ 0);
376 RunLoopUntil(
377 [this] { return this->mouse_input_listener()->SizeOfEvents() == 3; });
378
379 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
380
381 auto event_add = mouse_input_listener()->PopEvent();
382 auto event_down = mouse_input_listener()->PopEvent();
383 auto event_noop_move = mouse_input_listener()->PopEvent();
384
385 // If the first mouse event is a button press, Flutter first sends an ADD
386 // event with no buttons.
387 VerifyEvent(event_add,
388 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
389 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
390 /*expected_buttons=*/{},
391 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::ADD,
392 /*component_name=*/"mouse-input-view");
393
394 // Then Flutter sends a DOWN pointer event with the buttons we care about.
395 VerifyEvent(
396 event_down,
397 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
398 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
399 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
400 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::DOWN,
401 /*component_name=*/"mouse-input-view");
402
403 // Then Flutter sends a MOVE pointer event with no new information.
404 VerifyEvent(
405 event_noop_move,
406 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
407 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
408 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
409 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::MOVE,
410 /*component_name=*/"mouse-input-view");
411
412 SimulateMouseEvent(/* pressed_buttons = */ {}, /* movement_x = */ 0,
413 /* movement_y = */ 0);
414 RunLoopUntil(
415 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
416
417 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
418
419 auto event_up = mouse_input_listener()->PopEvent();
420 VerifyEvent(event_up,
421 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
422 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
423 /*expected_buttons=*/{},
424 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::UP,
425 /*component_name=*/"mouse-input-view");
426}
427
428TEST_P(MouseInputTest, DISABLED_FlutterMouseDownMoveUp) {
429 LaunchClient();
430
431 SimulateMouseEvent(
432 /* pressed_buttons = */ {fuchsia::ui::test::input::MouseButton::FIRST},
433 /* movement_x = */ 0, /* movement_y = */ 0);
434 RunLoopUntil(
435 [this] { return this->mouse_input_listener()->SizeOfEvents() == 3; });
436
437 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 3u);
438
439 auto event_add = mouse_input_listener()->PopEvent();
440 auto event_down = mouse_input_listener()->PopEvent();
441 auto event_noop_move = mouse_input_listener()->PopEvent();
442
443 // If the first mouse event is a button press, Flutter first sends an ADD
444 // event with no buttons.
445 VerifyEvent(event_add,
446 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
447 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
448 /*expected_buttons=*/{},
449 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::ADD,
450 /*component_name=*/"mouse-input-view");
451
452 // Then Flutter sends a DOWN pointer event with the buttons we care about.
453 VerifyEvent(
454 event_down,
455 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
456 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
457 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
458 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::DOWN,
459 /*component_name=*/"mouse-input-view");
460
461 // Then Flutter sends a MOVE pointer event with no new information.
462 VerifyEvent(
463 event_noop_move,
464 /*expected_x=*/static_cast<double>(display_width()) / 2.f,
465 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
466 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
467 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::MOVE,
468 /*component_name=*/"mouse-input-view");
469
470 SimulateMouseEvent(
471 /* pressed_buttons = */ {fuchsia::ui::test::input::MouseButton::FIRST},
472 /* movement_x = */ kClickToDragThreshold, /* movement_y = */ 0);
473 RunLoopUntil(
474 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
475
476 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
477
478 auto event_move = mouse_input_listener()->PopEvent();
479
480 VerifyEventLocationOnTheRightOfExpectation(
481 event_move,
482 /*expected_x_min=*/static_cast<double>(display_width()) / 2.f + 1,
483 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
484 /*expected_buttons=*/{fuchsia::ui::test::input::MouseButton::FIRST},
485 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::MOVE,
486 /*component_name=*/"mouse-input-view");
487
488 SimulateMouseEvent(/* pressed_buttons = */ {}, /* movement_x = */ 0,
489 /* movement_y = */ 0);
490 RunLoopUntil(
491 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
492
493 ASSERT_EQ(mouse_input_listener()->SizeOfEvents(), 1u);
494
495 auto event_up = mouse_input_listener()->PopEvent();
496
497 VerifyEventLocationOnTheRightOfExpectation(
498 event_up,
499 /*expected_x_min=*/static_cast<double>(display_width()) / 2.f + 1,
500 /*expected_y=*/static_cast<double>(display_height()) / 2.f,
501 /*expected_buttons=*/{},
502 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::UP,
503 /*component_name=*/"mouse-input-view");
504}
505
506// TODO(fxbug.dev/103098): This test shows the issue when sending mouse wheel as
507// the first event to Flutter.
508// 1. expect Flutter app receive 2 events: ADD - Scroll, but got 3 events: Move
509// - Scroll - Scroll.
510// 2. the first event flutter app received has random value in buttons field
511// Disabled until flutter rolls, since it changes the behavior of this issue.
512TEST_P(MouseInputTest, DISABLED_FlutterMouseWheelIssue103098) {
513 LaunchClient();
514
515 SimulateMouseScroll(/* pressed_buttons = */ {}, /* scroll_x = */ 1,
516 /* scroll_y = */ 0);
517 // Here we expected 2 events, ADD - Scroll, but got 3, Move - Scroll - Scroll.
518 RunLoopUntil(
519 [this] { return this->mouse_input_listener()->SizeOfEvents() == 3; });
520
521 double initial_x = static_cast<double>(display_width()) / 2.f;
522 double initial_y = static_cast<double>(display_height()) / 2.f;
523
524 auto event_1 = mouse_input_listener()->PopEvent();
525 EXPECT_NEAR(event_1.local_x(), initial_x, 1);
526 EXPECT_NEAR(event_1.local_y(), initial_y, 1);
527 // Flutter will scale the count of ticks to pixel.
528 EXPECT_GT(event_1.wheel_x_physical_pixel(), 0);
529 EXPECT_EQ(event_1.wheel_y_physical_pixel(), 0);
530 EXPECT_EQ(event_1.phase(), fuchsia::ui::test::input::MouseEventPhase::MOVE);
531
532 auto event_2 = mouse_input_listener()->PopEvent();
533 VerifyEvent(
534 event_2,
535 /*expected_x=*/initial_x,
536 /*expected_y=*/initial_y,
537 /*expected_buttons=*/{},
538 /*expected_phase=*/fuchsia::ui::test::input::MouseEventPhase::HOVER,
539 /*component_name=*/"mouse-input-view");
540 // Flutter will scale the count of ticks to pixel.
541 EXPECT_GT(event_2.wheel_x_physical_pixel(), 0);
542 EXPECT_EQ(event_2.wheel_y_physical_pixel(), 0);
543
544 auto event_3 = mouse_input_listener()->PopEvent();
545 VerifyEvent(
546 event_3,
547 /*expected_x=*/initial_x,
548 /*expected_y=*/initial_y,
549 /*expected_buttons=*/{},
550 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::HOVER,
551 /*component_name=*/"mouse-input-view");
552 // Flutter will scale the count of ticks to pixel.
553 EXPECT_GT(event_3.wheel_x_physical_pixel(), 0);
554 EXPECT_EQ(event_3.wheel_y_physical_pixel(), 0);
555}
556
557TEST_P(MouseInputTest, DISABLED_FlutterMouseWheel) {
558 LaunchClient();
559
560 double initial_x = static_cast<double>(display_width()) / 2.f + 1;
561 double initial_y = static_cast<double>(display_height()) / 2.f + 2;
562
563 // TODO(fxbug.dev/103098): Send a mouse move as the first event to workaround.
564 SimulateMouseEvent(/* pressed_buttons = */ {},
565 /* movement_x = */ 1, /* movement_y = */ 2);
566 RunLoopUntil(
567 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
568
569 auto event_add = mouse_input_listener()->PopEvent();
570 VerifyEvent(event_add,
571 /*expected_x=*/initial_x,
572 /*expected_y=*/initial_y,
573 /*expected_buttons=*/{},
574 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::ADD,
575 /*component_name=*/"mouse-input-view");
576
577 SimulateMouseScroll(/* pressed_buttons = */ {}, /* scroll_x = */ 1,
578 /* scroll_y = */ 0);
579 RunLoopUntil(
580 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
581
582 auto event_wheel_h = mouse_input_listener()->PopEvent();
583
584 VerifyEvent(
585 event_wheel_h,
586 /*expected_x=*/initial_x,
587 /*expected_y=*/initial_y,
588 /*expected_buttons=*/{},
589 /*expected_phase=*/fuchsia::ui::test::input::MouseEventPhase::HOVER,
590 /*component_name=*/"mouse-input-view");
591 // Flutter will scale the count of ticks to pixel.
592 EXPECT_GT(event_wheel_h.wheel_x_physical_pixel(), 0);
593 EXPECT_EQ(event_wheel_h.wheel_y_physical_pixel(), 0);
594
595 SimulateMouseScroll(/* pressed_buttons = */ {}, /* scroll_x = */ 0,
596 /* scroll_y = */ 1);
597 RunLoopUntil(
598 [this] { return this->mouse_input_listener()->SizeOfEvents() == 1; });
599
600 auto event_wheel_v = mouse_input_listener()->PopEvent();
601
602 VerifyEvent(
603 event_wheel_v,
604 /*expected_x=*/initial_x,
605 /*expected_y=*/initial_y,
606 /*expected_buttons=*/{},
607 /*expected_type=*/fuchsia::ui::test::input::MouseEventPhase::HOVER,
608 /*component_name=*/"mouse-input-view");
609 // Flutter will scale the count of ticks to pixel.
610 EXPECT_LT(event_wheel_v.wheel_y_physical_pixel(), 0);
611 EXPECT_EQ(event_wheel_v.wheel_x_physical_pixel(), 0);
612}
613
614} // namespace
615} // namespace mouse_input_test::testing
int32_t x
#define FML_LOG(severity)
Definition logging.h:101
double y
INSTANTIATE_TEST_SUITE_P(CompilerSuite, CompilerTest, ::testing::Values(TargetPlatform::kOpenGLES, TargetPlatform::kOpenGLDesktop, TargetPlatform::kMetalDesktop, TargetPlatform::kMetalIOS, TargetPlatform::kVulkan), [](const ::testing::TestParamInfo< CompilerTest::ParamType > &info) { return TargetPlatformToString(info.param);})
TEST_P(CompilerTest, CanCompile)