5#include <fuchsia/ui/pointer/cpp/fidl.h>
6#include <gtest/gtest.h>
7#include <lib/async-loop/cpp/loop.h>
8#include <lib/async-loop/default.h>
9#include <lib/fidl/cpp/binding_set.h>
15#include "flutter/fml/logging.h"
16#include "flutter/fml/macros.h"
35constexpr std::array<std::array<float, 2>, 2>
kRect = {{{0, 0}, {20, 20}}};
36constexpr std::array<float, 9>
kIdentity = {1, 0, 0, 0, 1, 0, 0, 0, 1};
39 .interaction_id = 2u};
66 fidl::BindingSet<fuchsia::ui::pointer::TouchSource> touch_source_bindings_;
67 fidl::BindingSet<fuchsia::ui::pointer::MouseSource> mouse_source_bindings_;
73 std::optional<std::vector<flutter::PointerData>> pointers;
74 pointer_delegate_->WatchLoop(
75 [&pointers](std::vector<flutter::PointerData> events) {
76 pointers = std::move(events);
81 std::vector<fup_TouchEvent> events =
87 {.interaction =
kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
89 touch_source_->ScheduleCallback(std::move(events));
92 ASSERT_TRUE(pointers.has_value());
93 ASSERT_EQ(pointers->size(), 2u);
94 EXPECT_EQ((*pointers)[0].time_stamp, 1111u);
95 EXPECT_EQ((*pointers)[1].time_stamp, 1111u);
99 std::optional<std::vector<flutter::PointerData>> pointers;
100 pointer_delegate_->WatchLoop(
101 [&pointers](std::vector<flutter::PointerData> events) {
102 pointers = std::move(events);
107 std::vector<fup_TouchEvent> events =
113 {.interaction =
kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
115 touch_source_->ScheduleCallback(std::move(events));
118 ASSERT_TRUE(pointers.has_value());
119 ASSERT_EQ(pointers->size(), 2u);
128 touch_source_->ScheduleCallback(std::move(events));
131 ASSERT_TRUE(pointers.has_value());
132 ASSERT_EQ(pointers->size(), 1u);
140 touch_source_->ScheduleCallback(std::move(events));
143 ASSERT_TRUE(pointers.has_value());
144 ASSERT_EQ(pointers->size(), 2u);
150 std::optional<std::vector<flutter::PointerData>> pointers;
151 pointer_delegate_->WatchLoop(
152 [&pointers](std::vector<flutter::PointerData> events) {
153 pointers = std::move(events);
158 std::vector<fup_TouchEvent> events =
164 {.interaction =
kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
166 touch_source_->ScheduleCallback(std::move(events));
169 ASSERT_TRUE(pointers.has_value());
170 ASSERT_EQ(pointers->size(), 2u);
179 touch_source_->ScheduleCallback(std::move(events));
182 ASSERT_TRUE(pointers.has_value());
183 ASSERT_EQ(pointers->size(), 1u);
188 std::optional<std::vector<flutter::PointerData>> pointers;
189 pointer_delegate_->WatchLoop(
190 [&pointers](std::vector<flutter::PointerData> events) {
191 pointers = std::move(events);
198 std::vector<fup_TouchEvent> events =
202 {{{0, 0}, {20, 20}}},
203 {1, 0, 0, 0, 1, 0, 0, 0, 1})
206 {.interaction =
kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
208 touch_source_->ScheduleCallback(std::move(events));
211 ASSERT_TRUE(pointers.has_value());
212 ASSERT_EQ(pointers->size(), 2u);
213 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
214 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
223 {{{0, 0}, {20, 20}}},
224 {1, 0, 0, 0, 1, 0, 10, 10, 1})
225 .AddSample(
kIxnOne, fup_EventPhase::CHANGE, {0.f, 0.f})
227 touch_source_->ScheduleCallback(std::move(events));
230 ASSERT_TRUE(pointers.has_value());
231 ASSERT_EQ(pointers->size(), 1u);
232 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
233 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
241 {{{0, 0}, {20, 20}}},
242 {0.5f, 0, 0, 0, 0.5f, 0, 0, 0, 1})
243 .AddSample(
kIxnOne, fup_EventPhase::CHANGE, {20.f, 20.f})
245 touch_source_->ScheduleCallback(std::move(events));
248 ASSERT_TRUE(pointers.has_value());
249 ASSERT_EQ(pointers->size(), 1u);
250 EXPECT_FLOAT_EQ((*pointers)[0].physical_x, 10.f);
251 EXPECT_FLOAT_EQ((*pointers)[0].physical_y, 10.f);
255 const float kSmallDiscrepancy = -0.00003f;
257 std::optional<std::vector<flutter::PointerData>> pointers;
258 pointer_delegate_->WatchLoop(
259 [&pointers](std::vector<flutter::PointerData> events) {
260 pointers = std::move(events);
264 std::vector<fup_TouchEvent> events =
270 {.interaction =
kIxnOne, .status = fup_TouchIxnStatus::GRANTED})
272 touch_source_->ScheduleCallback(std::move(events));
275 ASSERT_TRUE(pointers.has_value());
276 ASSERT_EQ(pointers->size(), 2u);
278 const auto& add_event = (*pointers)[0];
279 EXPECT_FLOAT_EQ(add_event.physical_x, 10.f);
280 EXPECT_FLOAT_EQ(add_event.physical_y, kSmallDiscrepancy);
282 const auto& down_event = (*pointers)[1];
283 EXPECT_FLOAT_EQ(down_event.physical_x, 10.f);
284 EXPECT_EQ(down_event.physical_y, 0.f);
289 pointer_delegate_->WatchLoop(
290 [&called](std::vector<flutter::PointerData> events) { called =
true; });
293 EXPECT_FALSE(called);
295 const auto responses = touch_source_->UploadedResponses();
296 ASSERT_TRUE(responses.has_value());
297 ASSERT_EQ(responses->size(), 0u);
301 std::optional<std::vector<flutter::PointerData>> pointers;
302 pointer_delegate_->WatchLoop(
303 [&pointers](std::vector<flutter::PointerData> events) {
304 pointers = std::move(events);
309 std::vector<fup_TouchEvent> events =
320 .
AddSample({.device_id = 0u, .pointer_id = 1u, .interaction_id = 3u},
323 events.emplace_back(std::move(
e1));
329 .
AddSample({.device_id = 0u, .pointer_id = 2u, .interaction_id = 3u},
332 events.emplace_back(std::move(e2));
338 .
AddSample({.device_id = 0u, .pointer_id = 3u, .interaction_id = 3u},
341 events.emplace_back(std::move(e3));
342 touch_source_->ScheduleCallback(std::move(events));
345 const auto responses = touch_source_->UploadedResponses();
346 ASSERT_TRUE(responses.has_value());
347 ASSERT_EQ(responses.value().size(), 4u);
349 EXPECT_FALSE(responses.value()[0].has_response_type());
351 EXPECT_TRUE(responses.value()[1].has_response_type());
352 EXPECT_EQ(responses.value()[1].response_type(), fup_TouchResponseType::YES);
353 EXPECT_TRUE(responses.value()[2].has_response_type());
354 EXPECT_EQ(responses.value()[2].response_type(), fup_TouchResponseType::YES);
355 EXPECT_TRUE(responses.value()[3].has_response_type());
356 EXPECT_EQ(responses.value()[3].response_type(), fup_TouchResponseType::YES);
360 std::optional<std::vector<flutter::PointerData>> pointers;
361 pointer_delegate_->WatchLoop(
362 [&pointers](std::vector<flutter::PointerData> events) {
363 pointers = std::move(events);
368 std::vector<fup_TouchEvent> events =
374 touch_source_->ScheduleCallback(std::move(events));
377 ASSERT_TRUE(pointers.has_value());
378 EXPECT_EQ(pointers.value().size(), 0u);
386 touch_source_->ScheduleCallback(std::move(events));
389 ASSERT_TRUE(pointers.has_value());
390 EXPECT_EQ(pointers.value().size(), 0u);
398 touch_source_->ScheduleCallback(std::move(events));
401 ASSERT_TRUE(pointers.has_value());
402 ASSERT_EQ(pointers.value().size(), 3u);
413 touch_source_->ScheduleCallback(std::move(events));
416 ASSERT_TRUE(pointers.has_value());
417 ASSERT_EQ(pointers.value().size(), 1u);
419 EXPECT_EQ(pointers.value()[0].time_stamp, 4444u);
424 std::optional<std::vector<flutter::PointerData>> pointers;
425 pointer_delegate_->WatchLoop(
426 [&pointers](std::vector<flutter::PointerData> events) {
427 pointers = std::move(events);
432 std::vector<fup_TouchEvent> events =
438 touch_source_->ScheduleCallback(std::move(events));
441 ASSERT_TRUE(pointers.has_value());
442 EXPECT_EQ(pointers.value().size(), 0u);
450 touch_source_->ScheduleCallback(std::move(events));
453 ASSERT_TRUE(pointers.has_value());
454 EXPECT_EQ(pointers.value().size(), 0u);
461 .AddResult({
kIxnOne, fup_TouchIxnStatus::GRANTED})
463 touch_source_->ScheduleCallback(std::move(events));
466 ASSERT_TRUE(pointers.has_value());
467 ASSERT_EQ(pointers.value().size(), 4u);
469 EXPECT_EQ(pointers.value()[0].time_stamp, 1111u);
471 EXPECT_EQ(pointers.value()[1].time_stamp, 1111u);
473 EXPECT_EQ(pointers.value()[2].time_stamp, 2222u);
475 EXPECT_EQ(pointers.value()[3].time_stamp, 3333u);
480 std::optional<std::vector<flutter::PointerData>> pointers;
481 pointer_delegate_->WatchLoop(
482 [&pointers](std::vector<flutter::PointerData> events) {
483 pointers = std::move(events);
488 std::vector<fup_TouchEvent> events =
493 .AddResult({
kIxnOne, fup_TouchIxnStatus::GRANTED})
495 touch_source_->ScheduleCallback(std::move(events));
498 ASSERT_TRUE(pointers.has_value());
499 ASSERT_EQ(pointers.value().size(), 2u);
509 touch_source_->ScheduleCallback(std::move(events));
512 ASSERT_TRUE(pointers.has_value());
513 ASSERT_EQ(pointers.value().size(), 1u);
519 std::optional<std::vector<flutter::PointerData>> pointers;
520 pointer_delegate_->WatchLoop(
521 [&pointers](std::vector<flutter::PointerData> events) {
522 pointers = std::move(events);
527 std::vector<fup_TouchEvent> events =
533 touch_source_->ScheduleCallback(std::move(events));
536 ASSERT_TRUE(pointers.has_value());
537 EXPECT_EQ(pointers.value().size(), 0u);
545 touch_source_->ScheduleCallback(std::move(events));
548 ASSERT_TRUE(pointers.has_value());
549 EXPECT_EQ(pointers.value().size(), 0u);
557 touch_source_->ScheduleCallback(std::move(events));
560 ASSERT_TRUE(pointers.has_value());
561 ASSERT_EQ(pointers.value().size(), 0u);
566 std::optional<std::vector<flutter::PointerData>> pointers;
567 pointer_delegate_->WatchLoop(
568 [&pointers](std::vector<flutter::PointerData> events) {
569 pointers = std::move(events);
574 std::vector<fup_TouchEvent> events =
580 touch_source_->ScheduleCallback(std::move(events));
583 ASSERT_TRUE(pointers.has_value());
584 EXPECT_EQ(pointers.value().size(), 0u);
592 touch_source_->ScheduleCallback(std::move(events));
595 ASSERT_TRUE(pointers.has_value());
596 EXPECT_EQ(pointers.value().size(), 0u);
603 .AddResult({
kIxnOne, fup_TouchIxnStatus::DENIED})
605 touch_source_->ScheduleCallback(std::move(events));
608 ASSERT_TRUE(pointers.has_value());
609 ASSERT_EQ(pointers.value().size(), 0u);
614 std::optional<std::vector<flutter::PointerData>> pointers;
615 pointer_delegate_->WatchLoop(
616 [&pointers](std::vector<flutter::PointerData> events) {
617 pointers = std::move(events);
622 .device_id = 1u, .pointer_id = 2u, .interaction_id = 2u};
625 std::vector<fup_TouchEvent> events =
636 events.emplace_back(std::move(ptr2));
637 touch_source_->ScheduleCallback(std::move(events));
640 ASSERT_TRUE(pointers.has_value());
641 EXPECT_EQ(pointers.value().size(), 0u);
647 .
AddResult({kIxnTwo, fup_TouchIxnStatus::GRANTED})
649 touch_source_->ScheduleCallback(std::move(events));
656 ASSERT_TRUE(pointers.has_value());
657 ASSERT_EQ(pointers.value().size(), 2u);
658 EXPECT_EQ(pointers.value()[0].pointer_identifier, 0);
659 EXPECT_EQ(pointers.value()[0].device, (int64_t)((1ul << 32) | 2u));
661 EXPECT_EQ(pointers.value()[1].pointer_identifier, 0);
662 EXPECT_EQ(pointers.value()[1].device, (int64_t)((1ul << 32) | 2u));
671 touch_source_->ScheduleCallback(std::move(events));
674 ASSERT_TRUE(pointers.has_value());
675 ASSERT_EQ(pointers.value().size(), 2u);
676 EXPECT_EQ(pointers.value()[0].pointer_identifier, 0);
677 EXPECT_EQ(pointers.value()[0].device, (int64_t)((1ul << 32) | 1u));
679 EXPECT_EQ(pointers.value()[1].pointer_identifier, 0);
680 EXPECT_EQ(pointers.value()[1].device, (int64_t)((1ul << 32) | 1u));
686 std::optional<std::vector<flutter::PointerData>> pointers;
687 pointer_delegate_->WatchLoop(
688 [&pointers](std::vector<flutter::PointerData> events) {
689 pointers = std::move(events);
693 std::vector<fup_MouseEvent> events =
701 mouse_source_->ScheduleCallback(std::move(events));
704 ASSERT_TRUE(pointers.has_value());
705 ASSERT_EQ(pointers.value().size(), 1u);
707 EXPECT_EQ(pointers.value()[0].signal_kind,
710 EXPECT_EQ(pointers.value()[0].buttons, 0);
711 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
712 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -20);
723 mouse_source_->ScheduleCallback(std::move(events));
726 ASSERT_TRUE(pointers.has_value());
727 ASSERT_EQ(pointers.value().size(), 1u);
729 EXPECT_EQ(pointers.value()[0].signal_kind,
732 EXPECT_EQ(pointers.value()[0].buttons, 0);
733 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 20);
734 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
739 std::optional<std::vector<flutter::PointerData>> pointers;
740 pointer_delegate_->WatchLoop(
741 [&pointers](std::vector<flutter::PointerData> events) {
742 pointers = std::move(events);
746 std::vector<fup_MouseEvent> events =
754 mouse_source_->ScheduleCallback(std::move(events));
757 ASSERT_TRUE(pointers.has_value());
758 ASSERT_EQ(pointers.value().size(), 1u);
760 EXPECT_EQ(pointers.value()[0].signal_kind,
763 EXPECT_EQ(pointers.value()[0].buttons, 0);
764 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
765 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -120);
776 mouse_source_->ScheduleCallback(std::move(events));
779 ASSERT_TRUE(pointers.has_value());
780 ASSERT_EQ(pointers.value().size(), 1u);
782 EXPECT_EQ(pointers.value()[0].signal_kind,
785 EXPECT_EQ(pointers.value()[0].buttons, 0);
786 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 120);
787 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
792 std::optional<std::vector<flutter::PointerData>> pointers;
793 pointer_delegate_->WatchLoop(
794 [&pointers](std::vector<flutter::PointerData> events) {
795 pointers = std::move(events);
799 std::vector<fup_MouseEvent> events =
807 mouse_source_->ScheduleCallback(std::move(events));
810 ASSERT_TRUE(pointers.has_value());
811 ASSERT_EQ(pointers.value().size(), 1u);
813 EXPECT_EQ(pointers.value()[0].signal_kind,
816 EXPECT_EQ(pointers.value()[0].buttons, 0);
817 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 0);
818 EXPECT_EQ(pointers.value()[0].scroll_delta_y, -120);
829 mouse_source_->ScheduleCallback(std::move(events));
832 ASSERT_TRUE(pointers.has_value());
833 ASSERT_EQ(pointers.value().size(), 1u);
835 EXPECT_EQ(pointers.value()[0].signal_kind,
838 EXPECT_EQ(pointers.value()[0].buttons, 0);
839 EXPECT_EQ(pointers.value()[0].scroll_delta_x, 120);
840 EXPECT_EQ(pointers.value()[0].scroll_delta_y, 0);
MouseEventBuilder & AddSample(uint32_t id, std::array< float, 2 > position, std::vector< uint8_t > pressed_buttons, std::array< int64_t, 2 > scroll, std::array< int64_t, 2 > scroll_in_physical_pixel, bool is_precision_scroll)
MouseEventBuilder & AddViewParameters(std::array< std::array< float, 2 >, 2 > view, std::array< std::array< float, 2 >, 2 > viewport, std::array< float, 9 > transform)
MouseEventBuilder & AddTime(zx_time_t time)
std::unique_ptr< FakeMouseSource > mouse_source_
std::unique_ptr< flutter_runner::PointerDelegate > pointer_delegate_
std::unique_ptr< FakeTouchSource > touch_source_
std::vector< fuchsia::ui::pointer::TouchEvent > BuildAsVector()
TouchEventBuilder & AddViewParameters(std::array< std::array< float, 2 >, 2 > view, std::array< std::array< float, 2 >, 2 > viewport, std::array< float, 9 > transform)
TouchEventBuilder & AddSample(fuchsia::ui::pointer::TouchInteractionId id, fuchsia::ui::pointer::EventPhase phase, std::array< float, 2 > position)
static TouchEventBuilder New()
TouchEventBuilder & AddTime(zx_time_t time)
TouchEventBuilder & AddResult(fuchsia::ui::pointer::TouchInteractionResult result)
def Build(configs, env, options)
fuchsia::ui::pointer::TouchEvent fup_TouchEvent
fuchsia::ui::pointer::TouchResponse fup_TouchResponse
fuchsia::ui::pointer::EventPhase fup_EventPhase
fuchsia::ui::pointer::TouchResponseType fup_TouchResponseType
constexpr uint32_t kMouseDeviceId
fuchsia::ui::pointer::TouchPointerSample fup_TouchPointerSample
fuchsia::ui::pointer::TouchInteractionStatus fup_TouchIxnStatus
constexpr std::array< int64_t, 2 > kNoScrollInPhysicalPixelDelta
fuchsia::ui::pointer::TouchInteractionResult fup_TouchIxnResult
fuchsia::ui::pointer::MouseEvent fup_MouseEvent
const bool kNotPrecisionScroll
const bool kPrecisionScroll
constexpr std::array< std::array< float, 2 >, 2 > kRect
constexpr std::array< float, 9 > kIdentity
fuchsia::ui::pointer::ViewParameters fup_ViewParameters
TEST_F(FocusDelegateTest, WatchCallbackSeries)
constexpr fup_TouchIxnId kIxnOne
fuchsia::ui::pointer::TouchInteractionId fup_TouchIxnId
#define EXPECT_TRUE(handle)