5#include <fuchsia/ui/pointerinjector/cpp/fidl.h>
6#include <fuchsia/ui/views/cpp/fidl.h>
7#include <gmock/gmock.h>
8#include <gtest/gtest.h>
9#include <lib/async-loop/cpp/loop.h>
10#include <lib/async-loop/default.h>
11#include <lib/async/cpp/task.h>
12#include <lib/zx/eventpair.h>
14#include <lib/fidl/cpp/binding_set.h>
31 static constexpr std::array<float, 9> kIdentityMatrix = {
39 rapidjson::Document document;
41 if (document.HasParseError() || !document.IsObject()) {
43 return rapidjson::Value();
45 return document.GetObject();
48zx_koid_t ExtractKoid(
const zx::object_base&
object) {
49 zx_info_handle_basic_t
info{};
50 if (
object.get_info(ZX_INFO_HANDLE_BASIC, &
info,
sizeof(
info),
nullptr,
52 return ZX_KOID_INVALID;
59 return ExtractKoid(view_ref.reference);
62class PlatformMessageBuilder {
64 PlatformMessageBuilder& SetViewId(uint64_t view_id) {
69 PlatformMessageBuilder& SetPointerX(
float x) {
74 PlatformMessageBuilder& SetPointerY(
float y) {
79 PlatformMessageBuilder& SetPhase(
int phase) {
84 PlatformMessageBuilder& SetPointerId(
int pointer_id) {
85 pointer_id_ = pointer_id;
89 PlatformMessageBuilder& SetTraceFlowId(
int trace_flow_id) {
90 trace_flow_id_ = trace_flow_id;
94 PlatformMessageBuilder& SetLogicalWidth(
float width) {
99 PlatformMessageBuilder& SetLogicalHeight(
float height) {
104 PlatformMessageBuilder& SetTimestamp(
int timestamp) {
105 timestamp_ = timestamp;
109 rapidjson::Value
Build() {
111 message <<
"{" <<
" \"method\":\""
113 <<
" \"args\": {" <<
" \"viewId\":" << view_id_ <<
","
114 <<
" \"x\":" << pointer_x_ <<
","
115 <<
" \"y\":" << pointer_y_ <<
","
116 <<
" \"phase\":" << phase_ <<
","
117 <<
" \"pointerId\":" << pointer_id_ <<
","
118 <<
" \"traceFlowId\":" << trace_flow_id_ <<
","
119 <<
" \"viewRef\":" <<
view_ref_.reference.get() <<
","
120 <<
" \"logicalWidth\":" << width_ <<
","
121 <<
" \"logicalHeight\":" << height_ <<
","
122 <<
" \"timestamp\":" << timestamp_ <<
" }" <<
"}";
127 uint64_t view_id_ = 0;
128 float pointer_x_ = 0.f, pointer_y_ = 0.f;
129 int phase_ = 1, pointer_id_ = 0, trace_flow_id_ = 0;
131 float width_ = 0.f, height_ = 0.f;
138 public ::testing::WithParamInterface<bool> {
141 : loop_(&kAsyncLoopConfigAttachToCurrentThread) {}
150 auto canceled = std::make_shared<bool>(
false);
151 bool timed_out =
false;
152 async::PostDelayedTask(
154 [loop, canceled, &timed_out] {
176 while (zx::clock::get_monotonic() < timeout_deadline &&
177 loop_.GetState() == ASYNC_LOOP_RUNNABLE) {
183 if (
step == zx::duration::infinite()) {
186 loop_.Run(timeout_deadline,
true);
189 RunGivenLoopWithTimeout(&loop_,
step);
199 RunLoopWithTimeoutOrUntil(std::move(condition), zx::duration::infinite(),
204 fuchsia::ui::views::ViewRefControl view_ref_control;
205 fuchsia::ui::views::ViewRef view_ref;
207 0u, &view_ref_control.reference, &view_ref.reference);
208 ASSERT_EQ(status, ZX_OK);
209 view_ref_control.reference.replace(
210 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
211 &view_ref_control.reference);
212 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
214 host_view_ref_ = std::move(view_ref);
217 registry_ = std::make_unique<MockInjectorRegistry>(registry.NewRequest());
220 fidl::Clone(host_view_ref_, &host_view_ref_clone);
222 pointer_injector_delegate_ = std::make_unique<PointerInjectorDelegate>(
223 std::move(registry), std::move(host_view_ref_clone));
227 std::optional<fuv_ViewRef> view_ref = std::nullopt) {
229 if (view_ref.has_value()) {
230 ref = std::move(*view_ref);
232 fuchsia::ui::views::ViewRefControl view_ref_control;
233 fuchsia::ui::views::ViewRef view_ref;
235 0u, &view_ref_control.reference, &view_ref.reference);
236 ASSERT_EQ(status, ZX_OK);
237 view_ref_control.reference.replace(
238 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
239 &view_ref_control.reference);
240 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
242 ref = std::move(view_ref);
244 pointer_injector_delegate_->OnCreateView(view_id, std::move(ref));
256 const uint64_t view_id = 1;
265 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
274 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
283 EXPECT_FALSE(pointer_injector_delegate_->HandlePlatformMessage(
290 const uint64_t num_events = 150;
294 const uint64_t view_id = 1;
298 fuchsia::ui::views::ViewRefControl view_ref_control;
299 fuchsia::ui::views::ViewRef view_ref;
301 0u, &view_ref_control.reference, &view_ref.reference);
302 ASSERT_EQ(status, ZX_OK);
303 view_ref_control.reference.replace(
304 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
305 &view_ref_control.reference);
306 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
308 for (
size_t i = 0;
i < num_events;
i++) {
311 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
312 PlatformMessageBuilder().SetViewId(view_id).
Build(), response));
314 response->ExpectCompleted(
"[0]");
320 const uint64_t view_id = 2;
324 fuchsia::ui::views::ViewRefControl view_ref_control;
325 fuchsia::ui::views::ViewRef view_ref;
327 0u, &view_ref_control.reference, &view_ref.reference);
328 ASSERT_EQ(status, ZX_OK);
329 view_ref_control.reference.replace(
330 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
331 &view_ref_control.reference);
332 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
334 for (
size_t i = 0;
i < num_events;
i++) {
337 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
338 PlatformMessageBuilder().SetViewId(view_id).
Build(), response));
340 response->ExpectCompleted(
"[0]");
347 [
this] {
return registry_->num_events_received() == 2 * num_events; });
355 ViewsDontReceivePointerEventsBeforeCreation) {
356 const uint64_t num_events = 150;
357 const uint64_t view_id_1 = 1;
361 fuchsia::ui::views::ViewRefControl view_ref_control;
362 fuchsia::ui::views::ViewRef view_ref;
364 0u, &view_ref_control.reference, &view_ref.reference);
365 ASSERT_EQ(status, ZX_OK);
366 view_ref_control.reference.replace(
367 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
368 &view_ref_control.reference);
369 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
371 for (
size_t i = 0;
i < num_events;
i++) {
378 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
379 PlatformMessageBuilder().SetViewId(view_id_1).
Build(), response));
383 const uint64_t view_id_2 = 2;
387 fuchsia::ui::views::ViewRefControl view_ref_control;
388 fuchsia::ui::views::ViewRef view_ref;
390 0u, &view_ref_control.reference, &view_ref.reference);
391 ASSERT_EQ(status, ZX_OK);
392 view_ref_control.reference.replace(
393 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
394 &view_ref_control.reference);
395 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
397 for (
size_t i = 0;
i < num_events;
i++) {
404 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
405 PlatformMessageBuilder().SetViewId(view_id_2).
Build(), response));
412 EXPECT_TRUE(registry_->num_events_received() == 0);
418 const uint64_t view_id = 1;
421 const int phase = 2, pointer_id = 5, trace_flow_id = 5, timestamp = 10;
425 fuchsia::ui::views::ViewRefControl view_ref_control;
426 fuchsia::ui::views::ViewRef view_ref;
428 0u, &view_ref_control.reference, &view_ref.reference);
429 ZX_ASSERT(status == ZX_OK);
430 view_ref_control.reference.replace(
431 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
432 &view_ref_control.reference);
433 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
437 fidl::Clone(view_ref, &view_ref_clone);
438 CreateView(view_id, std::move(view_ref_clone));
441 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
442 PlatformMessageBuilder()
447 .SetPointerId(pointer_id)
448 .SetTraceFlowId(trace_flow_id)
449 .SetLogicalWidth(
width)
451 .SetTimestamp(timestamp)
455 response->ExpectCompleted(
"[0]");
459 RunLoopUntil([
this] {
return registry_->num_events_received() == 1; });
463 ASSERT_TRUE(registry_->num_register_calls() == 1);
465 const auto& config = registry_->config();
467 ASSERT_TRUE(config.has_device_id());
468 EXPECT_EQ(config.device_id(), 1u);
470 ASSERT_TRUE(config.has_device_type());
471 EXPECT_EQ(config.device_type(), fup_DeviceType::TOUCH);
473 ASSERT_TRUE(config.has_dispatch_policy());
474 EXPECT_EQ(config.dispatch_policy(), fup_DispatchPolicy::EXCLUSIVE_TARGET);
476 ASSERT_TRUE(config.has_context());
477 ASSERT_TRUE(config.context().is_view());
478 EXPECT_EQ(ExtractKoid(config.context().view()), ExtractKoid(host_view_ref_));
480 ASSERT_TRUE(config.has_target());
481 ASSERT_TRUE(config.target().is_view());
482 EXPECT_EQ(ExtractKoid(config.target().view()), ExtractKoid(view_ref));
484 ASSERT_TRUE(config.has_viewport());
485 ASSERT_TRUE(config.viewport().has_viewport_to_context_transform());
486 EXPECT_EQ(config.viewport().viewport_to_context_transform(), kIdentityMatrix);
488 std::array<std::array<float, 2>, 2> extents{{{0, 0}, {
width,
height}}};
489 ASSERT_TRUE(config.viewport().has_extents());
490 EXPECT_EQ(config.viewport().extents(), extents);
496 const uint64_t view_id = 1;
499 const int phase = 2, pointer_id = 5, trace_flow_id = 5, timestamp = 10;
503 fuchsia::ui::views::ViewRefControl view_ref_control;
504 fuchsia::ui::views::ViewRef view_ref;
506 0u, &view_ref_control.reference, &view_ref.reference);
507 ZX_ASSERT(status == ZX_OK);
508 view_ref_control.reference.replace(
509 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
510 &view_ref_control.reference);
511 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
515 fidl::Clone(view_ref, &view_ref_clone);
516 CreateView(view_id, std::move(view_ref_clone));
519 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
520 PlatformMessageBuilder()
525 .SetPointerId(pointer_id)
526 .SetTraceFlowId(trace_flow_id)
527 .SetLogicalWidth(
width)
529 .SetTimestamp(timestamp)
533 response->ExpectCompleted(
"[0]");
537 RunLoopUntil([
this] {
return registry_->num_events_received() == 1; });
541 ASSERT_TRUE(registry_->num_register_calls() == 1);
543 const auto& events = registry_->events();
545 ASSERT_EQ(events.size(), 1u);
547 const auto&
event = events[0];
549 ASSERT_TRUE(
event.has_timestamp());
550 EXPECT_EQ(
event.timestamp(), timestamp);
552 ASSERT_TRUE(
event.has_trace_flow_id());
553 EXPECT_EQ(
event.trace_flow_id(),
static_cast<uint64_t
>(trace_flow_id));
555 ASSERT_TRUE(
event.has_data());
556 ASSERT_TRUE(
event.data().is_pointer_sample());
558 const auto& pointer_sample =
event.data().pointer_sample();
560 ASSERT_TRUE(pointer_sample.has_pointer_id());
561 ASSERT_TRUE(pointer_sample.has_phase());
562 ASSERT_TRUE(pointer_sample.has_position_in_viewport());
563 EXPECT_EQ(pointer_sample.pointer_id(),
static_cast<uint32_t
>(pointer_id));
564 EXPECT_EQ(pointer_sample.phase(),
static_cast<fup_EventPhase>(phase));
565 EXPECT_THAT(pointer_sample.position_in_viewport(),
566 ::testing::ElementsAre(
x,
y));
570 const uint64_t view_id = 1, num_events = 150;
572 fuchsia::ui::views::ViewRefControl view_ref_control;
573 fuchsia::ui::views::ViewRef view_ref;
575 0u, &view_ref_control.reference, &view_ref.reference);
576 ZX_ASSERT(status == ZX_OK);
577 view_ref_control.reference.replace(
578 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
579 &view_ref_control.reference);
580 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
586 for (
size_t i = 0;
i < num_events;
i++) {
589 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
590 PlatformMessageBuilder().SetViewId(view_id).
Build(), response));
592 response->ExpectCompleted(
"[0]");
596 pointer_injector_delegate_->OnDestroyView(view_id);
601 EXPECT_FALSE(RunLoopWithTimeoutOrUntil(
602 [
this] {
return registry_->num_events_received() == num_events; },
605 EXPECT_LT(registry_->num_events_received(), num_events);
609 const uint64_t view_id = 1, num_events = 150;
611 fuchsia::ui::views::ViewRefControl view_ref_control;
612 fuchsia::ui::views::ViewRef view_ref;
614 0u, &view_ref_control.reference, &view_ref.reference);
615 ZX_ASSERT(status == ZX_OK);
616 view_ref_control.reference.replace(
617 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
618 &view_ref_control.reference);
619 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
625 for (
size_t i = 0;
i < num_events;
i++) {
628 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
629 PlatformMessageBuilder()
631 .SetPointerId(
static_cast<uint32_t
>(
i))
635 response->ExpectCompleted(
"[0]");
641 [
this] {
return registry_->num_events_received() == num_events; });
645 ASSERT_TRUE(registry_->num_register_calls() == 1);
647 auto& events = registry_->events();
652 for (
size_t i = 0;
i < events.size() - 1;
i++) {
653 ASSERT_TRUE(events[
i].has_data());
654 ASSERT_TRUE(events[
i + 1].has_data());
655 ASSERT_TRUE(events[
i].
data().is_pointer_sample());
656 ASSERT_TRUE(events[
i + 1].
data().is_pointer_sample());
658 const auto& pointer_sample_1 = events[
i].data().pointer_sample();
659 const auto& pointer_sample_2 = events[
i + 1].data().pointer_sample();
661 ASSERT_TRUE(pointer_sample_1.has_pointer_id());
662 ASSERT_TRUE(pointer_sample_2.has_pointer_id());
664 EXPECT_TRUE(pointer_sample_1.pointer_id() < pointer_sample_2.pointer_id());
669 const uint64_t view_id = 1;
670 const int pointer_id = 1;
671 fuchsia::ui::views::ViewRefControl view_ref_control;
672 fuchsia::ui::views::ViewRef view_ref;
674 0u, &view_ref_control.reference, &view_ref.reference);
675 ZX_ASSERT(status == ZX_OK);
676 view_ref_control.reference.replace(
677 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
678 &view_ref_control.reference);
679 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
686 fidl::Clone(view_ref, &view_ref_clone);
687 CreateView(view_id, std::move(view_ref_clone));
689 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
690 PlatformMessageBuilder()
692 .SetPointerId(pointer_id)
696 response->ExpectCompleted(
"[0]");
700 RunLoopUntil([
this] {
return registry_->num_events_received() == 1; });
704 ASSERT_TRUE(registry_->num_register_calls() == 1);
707 registry_->ClearBindings();
710 EXPECT_TRUE(pointer_injector_delegate_->HandlePlatformMessage(
711 PlatformMessageBuilder()
713 .SetPointerId(pointer_id)
717 response_2->ExpectCompleted(
"[0]");
721 RunLoopUntil([
this] {
return registry_->num_events_received() == 2; });
724 ASSERT_TRUE(registry_->num_register_calls() == 2);
static int step(int x, SkScalar min, SkScalar max)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static sk_sp< Effect > Create()
static constexpr auto kPointerInjectorMethodPrefix
fuv_ViewRef host_view_ref_
PointerInjectorDelegateTest()
void CreateView(uint64_t view_id, std::optional< fuv_ViewRef > view_ref=std::nullopt)
std::unique_ptr< PointerInjectorDelegate > pointer_injector_delegate_
bool RunGivenLoopWithTimeout(async::Loop *loop, zx::duration timeout)
void RunLoopUntil(fit::function< bool()> condition, zx::duration step=zx::msec(10))
bool RunLoopWithTimeoutOrUntil(fit::function< bool()> condition, zx::duration timeout, zx::duration step)
std::unique_ptr< MockInjectorRegistry > registry_
#define FML_LOG(severity)
rapidjson::Value ParsePlatformMessage(std::string json)
Dart_NativeFunction function
def Build(configs, env, options)
fuchsia::ui::pointer::EventPhase fup_EventPhase
TEST_P(PointerInjectorDelegateTest, DeviceRetriesRegisterWhenClosed)
fuchsia::ui::pointerinjector::RegistryHandle fup_RegistryHandle
fuchsia::ui::pointerinjector::DeviceType fup_DeviceType
fuchsia::ui::views::ViewRef fuv_ViewRef
fuchsia::ui::pointerinjector::DispatchPolicy fup_DispatchPolicy
INSTANTIATE_TEST_SUITE_P(PointerInjectorDelegateParameterizedTest, PointerInjectorDelegateTest, ::testing::Bool())
def timeout(deadline, cmd)
static double time(int loops, Benchmark *bench, Target *target)
std::shared_ptr< const fml::Mapping > data
#define EXPECT_TRUE(handle)