From bb62e43f4b5a7506c7d6a5c5472d4c63441100b1 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 20:14:24 +0000 Subject: [PATCH 1/9] Add embedding-flutter test --- .../integration/embedder/child-view/BUILD.gn | 7 + .../embedder/child-view/lib/child_view.dart | 33 ++- .../embedder/child-view/meta/child-view.cml | 7 + .../embedder/flutter-embedder-test.cc | 220 ++++++++--------- .../integration/embedder/parent-view/BUILD.gn | 1 + .../embedder/parent-view/lib/parent_view.dart | 41 +++- .../embedder/parent-view/meta/parent-view.cml | 2 + .../tests/integration/touch-input/BUILD.gn | 5 + .../tests/integration/touch-input/README.md | 5 +- .../embedding-flutter-view/BUILD.gn | 42 ++++ .../lib/embedding-flutter-view.dart | 176 ++++++++++++++ .../meta/embedding-flutter-view.cml | 38 +++ .../embedding-flutter-view/pubspec.yaml | 0 .../touch-input/touch-input-test.cc | 230 +++++++++++++----- .../lib/touch-input-view.dart | 38 +-- .../meta/touch-input-view.cml | 4 - .../integration/utils/portable_ui_test.cc | 48 +++- .../integration/utils/portable_ui_test.h | 9 +- .../fuchsia/devshell/run_integration_test.sh | 2 +- 19 files changed, 686 insertions(+), 222 deletions(-) create mode 100644 shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn create mode 100644 shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart create mode 100644 shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/meta/embedding-flutter-view.cml create mode 100644 shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn index dedf77c3eb950..1601a7c02f34d 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn @@ -10,6 +10,13 @@ import("//flutter/tools/fuchsia/gn-sdk/package.gni") dart_library("lib") { package_name = "child-view" sources = [ "child_view.dart" ] + + deps = [ + "//flutter/shell/platform/fuchsia/dart:args", + "//flutter/tools/fuchsia/dart:fuchsia_services", + "//flutter/tools/fuchsia/dart:zircon", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", + ] } flutter_component("component") { diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart index 5b71294b700d5..f3d6f8835d951 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart @@ -2,8 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:typed_data'; import 'dart:ui'; +import 'package:args/args.dart'; +import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; +import 'package:fuchsia_services/services.dart'; +import 'package:zircon/zircon.dart'; + void main(List args) { print('child-view: starting'); @@ -17,6 +23,8 @@ class TestApp { Color _backgroundColor = _pink; + final _responseListener = test_touch.TouchInputListenerProxy(); + void run() { window.onPointerDataPacket = (PointerDataPacket packet) { this.pointerDataPacket(packet); @@ -49,11 +57,34 @@ class TestApp { } void pointerDataPacket(PointerDataPacket packet) { - for (final data in packet.data) { + int nowNanos = System.clockGetMonotonic(); + + for (PointerData data in packet.data) { + print('child-view received tap: ${data.toStringFull()}'); + if (data.change == PointerChange.down) { this._backgroundColor = _yellow; } + + if (data.change == PointerChange.down || data.change == PointerChange.move) { + Incoming.fromSvcPath() + ..connectToService(_responseListener) + ..close(); + + _respond(test_touch.TouchInputListenerReportTouchInputRequest( + localX: data.physicalX, + localY: data.physicalY, + timeReceived: nowNanos, + componentName: 'child-view', + )); + } } + window.scheduleFrame(); } + + void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async { + print('child-view reporting touch input to TouchInputListener'); + await _responseListener.reportTouchInput(request); + } } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml index c1aab3a83d063..a70ee8d30eeb3 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml @@ -21,4 +21,11 @@ from: "self", }, ], + use: [ + { + protocol: [ + "fuchsia.ui.test.input.TouchInputListener", + ] + } + ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc index 20200e0725c58..557f917903a81 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc @@ -86,36 +86,36 @@ constexpr auto kTestUiStackRef = ChildRef{kTestUiStack}; constexpr fuchsia_test_utils::Color kParentBackgroundColor = {0x00, 0x00, 0xFF, 0xFF}; // Blue -constexpr fuchsia_test_utils::Color kParentTappedColor = {0x00, 0x00, 0x00, - 0xFF}; // Black +// constexpr fuchsia_test_utils::Color kParentTappedColor = {0x00, 0x00, 0x00, +// 0xFF}; // Black constexpr fuchsia_test_utils::Color kChildBackgroundColor = {0xFF, 0x00, 0xFF, 0xFF}; // Pink constexpr fuchsia_test_utils::Color kChildTappedColor = {0xFF, 0xFF, 0x00, 0xFF}; // Yellow // TODO(fxb/64201): Remove forced opacity colors when Flatland is enabled. -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor1 = { - 0x00, 0xFF, 0x0E, 0xFF}; // Green, blended with blue (FEMU local) -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor2 = { - 0x0E, 0xFF, 0x0E, 0xFF}; // Green, blended with pink (FEMU local) -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor3 = { - 0x00, 0xFF, 0x0D, 0xFF}; // Green, blended with blue (AEMU infra) -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor4 = { - 0x0D, 0xFF, 0x0D, 0xFF}; // Green, blended with pink (AEMU infra) -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor5 = { - 0x00, 0xFE, 0x0D, 0xFF}; // Green, blended with blue (NUC) -constexpr fuchsia_test_utils::Color kOverlayBackgroundColor6 = { - 0x0D, 0xFF, 0x00, 0xFF}; // Green, blended with pink (NUC) - -static size_t OverlayPixelCount( - std::map& histogram) { - return histogram[kOverlayBackgroundColor1] + - histogram[kOverlayBackgroundColor2] + - histogram[kOverlayBackgroundColor3] + - histogram[kOverlayBackgroundColor4] + - histogram[kOverlayBackgroundColor5] + - histogram[kOverlayBackgroundColor6]; -} +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor1 = { +// 0x00, 0xFF, 0x0E, 0xFF}; // Green, blended with blue (FEMU local) +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor2 = { +// 0x0E, 0xFF, 0x0E, 0xFF}; // Green, blended with pink (FEMU local) +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor3 = { +// 0x00, 0xFF, 0x0D, 0xFF}; // Green, blended with blue (AEMU infra) +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor4 = { +// 0x0D, 0xFF, 0x0D, 0xFF}; // Green, blended with pink (AEMU infra) +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor5 = { +// 0x00, 0xFE, 0x0D, 0xFF}; // Green, blended with blue (NUC) +// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor6 = { +// 0x0D, 0xFF, 0x00, 0xFF}; // Green, blended with pink (NUC) + +// static size_t OverlayPixelCount( +// std::map& histogram) { +// return histogram[kOverlayBackgroundColor1] + +// histogram[kOverlayBackgroundColor2] + +// histogram[kOverlayBackgroundColor3] + +// histogram[kOverlayBackgroundColor4] + +// histogram[kOverlayBackgroundColor5] + +// histogram[kOverlayBackgroundColor6]; +// } // Timeout for Scenic's |TakeScreenshot| FIDL call. constexpr zx::duration kScreenshotTimeout = zx::sec(10); @@ -473,21 +473,21 @@ void FlutterEmbedderTest::TryInject(int32_t x, int32_t y) { dispatcher(), [this, x, y] { TryInject(x, y); }, kTapRetryInterval); } -TEST_F(FlutterEmbedderTest, Embedding) { - LaunchParentViewInRealm(); - - // Take screenshot until we see the child-view's embedded color. - ASSERT_TRUE(TakeScreenshotUntil( - kChildBackgroundColor, - [](std::map histogram) { - // Expect parent and child background colors, with parent color > child - // color. - EXPECT_GT(histogram[kParentBackgroundColor], 0u); - EXPECT_GT(histogram[kChildBackgroundColor], 0u); - EXPECT_GT(histogram[kParentBackgroundColor], - histogram[kChildBackgroundColor]); - })); -} +// TEST_F(FlutterEmbedderTest, Embedding) { +// LaunchParentViewInRealm(); + +// // Take screenshot until we see the child-view's embedded color. +// ASSERT_TRUE(TakeScreenshotUntil( +// kChildBackgroundColor, +// [](std::map histogram) { +// // Expect parent and child background colors, with parent color > child +// // color. +// EXPECT_GT(histogram[kParentBackgroundColor], 0u); +// EXPECT_GT(histogram[kChildBackgroundColor], 0u); +// EXPECT_GT(histogram[kParentBackgroundColor], +// histogram[kChildBackgroundColor]); +// })); +// } TEST_F(FlutterEmbedderTest, HittestEmbedding) { LaunchParentViewInRealm(); @@ -512,76 +512,76 @@ TEST_F(FlutterEmbedderTest, HittestEmbedding) { })); } -TEST_F(FlutterEmbedderTest, HittestDisabledEmbedding) { - LaunchParentViewInRealm({"--no-hitTestable"}); - - // Take screenshots until we see the child-view's embedded color. - ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); - - // Simulate a tap at the center of the child view. - TryInject(/* x = */ 0, /* y = */ 0); - - // The parent-view should change color. - ASSERT_TRUE(TakeScreenshotUntil( - kParentTappedColor, - [](std::map histogram) { - // Expect parent and child background colors, with parent color > child - // color. - EXPECT_EQ(histogram[kParentBackgroundColor], 0u); - EXPECT_GT(histogram[kParentTappedColor], 0u); - EXPECT_GT(histogram[kChildBackgroundColor], 0u); - EXPECT_EQ(histogram[kChildTappedColor], 0u); - EXPECT_GT(histogram[kParentTappedColor], - histogram[kChildBackgroundColor]); - })); -} - -TEST_F(FlutterEmbedderTest, EmbeddingWithOverlay) { - LaunchParentViewInRealm({"--showOverlay"}); - - // Take screenshot until we see the child-view's embedded color. - ASSERT_TRUE(TakeScreenshotUntil( - kChildBackgroundColor, - [](std::map histogram) { - // Expect parent, overlay and child background colors. - // With parent color > child color and overlay color > child color. - const size_t overlay_pixel_count = OverlayPixelCount(histogram); - EXPECT_GT(histogram[kParentBackgroundColor], 0u); - EXPECT_GT(overlay_pixel_count, 0u); - EXPECT_GT(histogram[kChildBackgroundColor], 0u); - EXPECT_GT(histogram[kParentBackgroundColor], - histogram[kChildBackgroundColor]); - EXPECT_GT(overlay_pixel_count, histogram[kChildBackgroundColor]); - })); -} - -TEST_F(FlutterEmbedderTest, HittestEmbeddingWithOverlay) { - LaunchParentViewInRealm({"--showOverlay"}); - - // Take screenshot until we see the child-view's embedded color. - ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); - - // The bottom-left corner of the overlay is at the center of the screen, - // which is at (0, 0) in the injection coordinate space. Inject a pointer - // event just outside the overlay's bounds, and ensure that it goes to the - // embedded view. - TryInject(/* x = */ -1, /* y = */ 1); - - // Take screenshot until we see the child-view's tapped color. - ASSERT_TRUE(TakeScreenshotUntil( - kChildTappedColor, - [](std::map histogram) { - // Expect parent, overlay and child background colors. - // With parent color > child color and overlay color > child color. - const size_t overlay_pixel_count = OverlayPixelCount(histogram); - EXPECT_GT(histogram[kParentBackgroundColor], 0u); - EXPECT_GT(overlay_pixel_count, 0u); - EXPECT_EQ(histogram[kChildBackgroundColor], 0u); - EXPECT_GT(histogram[kChildTappedColor], 0u); - EXPECT_GT(histogram[kParentBackgroundColor], - histogram[kChildTappedColor]); - EXPECT_GT(overlay_pixel_count, histogram[kChildTappedColor]); - })); -} +// TEST_F(FlutterEmbedderTest, HittestDisabledEmbedding) { +// LaunchParentViewInRealm({"--no-hitTestable"}); + +// // Take screenshots until we see the child-view's embedded color. +// ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); + +// // Simulate a tap at the center of the child view. +// TryInject(/* x = */ 0, /* y = */ 0); + +// // The parent-view should change color. +// ASSERT_TRUE(TakeScreenshotUntil( +// kParentTappedColor, +// [](std::map histogram) { +// // Expect parent and child background colors, with parent color > child +// // color. +// EXPECT_EQ(histogram[kParentBackgroundColor], 0u); +// EXPECT_GT(histogram[kParentTappedColor], 0u); +// EXPECT_GT(histogram[kChildBackgroundColor], 0u); +// EXPECT_EQ(histogram[kChildTappedColor], 0u); +// EXPECT_GT(histogram[kParentTappedColor], +// histogram[kChildBackgroundColor]); +// })); +// } + +// TEST_F(FlutterEmbedderTest, EmbeddingWithOverlay) { +// LaunchParentViewInRealm({"--showOverlay"}); + +// // Take screenshot until we see the child-view's embedded color. +// ASSERT_TRUE(TakeScreenshotUntil( +// kChildBackgroundColor, +// [](std::map histogram) { +// // Expect parent, overlay and child background colors. +// // With parent color > child color and overlay color > child color. +// const size_t overlay_pixel_count = OverlayPixelCount(histogram); +// EXPECT_GT(histogram[kParentBackgroundColor], 0u); +// EXPECT_GT(overlay_pixel_count, 0u); +// EXPECT_GT(histogram[kChildBackgroundColor], 0u); +// EXPECT_GT(histogram[kParentBackgroundColor], +// histogram[kChildBackgroundColor]); +// EXPECT_GT(overlay_pixel_count, histogram[kChildBackgroundColor]); +// })); +// } + +// TEST_F(FlutterEmbedderTest, HittestEmbeddingWithOverlay) { +// LaunchParentViewInRealm({"--showOverlay"}); + +// // Take screenshot until we see the child-view's embedded color. +// ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); + +// // The bottom-left corner of the overlay is at the center of the screen, +// // which is at (0, 0) in the injection coordinate space. Inject a pointer +// // event just outside the overlay's bounds, and ensure that it goes to the +// // embedded view. +// TryInject(/* x = */ -1, /* y = */ 1); + +// // Take screenshot until we see the child-view's tapped color. +// ASSERT_TRUE(TakeScreenshotUntil( +// kChildTappedColor, +// [](std::map histogram) { +// // Expect parent, overlay and child background colors. +// // With parent color > child color and overlay color > child color. +// const size_t overlay_pixel_count = OverlayPixelCount(histogram); +// EXPECT_GT(histogram[kParentBackgroundColor], 0u); +// EXPECT_GT(overlay_pixel_count, 0u); +// EXPECT_EQ(histogram[kChildBackgroundColor], 0u); +// EXPECT_GT(histogram[kChildTappedColor], 0u); +// EXPECT_GT(histogram[kParentBackgroundColor], +// histogram[kChildTappedColor]); +// EXPECT_GT(overlay_pixel_count, histogram[kChildTappedColor]); +// })); +// } } // namespace flutter_embedder_test diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn index ceaf8299f4a1b..627c8467473b5 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn @@ -19,6 +19,7 @@ dart_library("lib") { "//flutter/tools/fuchsia/fidl:fuchsia.sys", "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart index 5fd521661150d..9d41e52476f3f 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart @@ -10,6 +10,7 @@ import 'dart:ui'; import 'package:args/args.dart'; import 'package:fidl_fuchsia_ui_app/fidl_async.dart'; import 'package:fidl_fuchsia_ui_views/fidl_async.dart'; +import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; import 'package:fuchsia_services/services.dart'; import 'package:vector_math/vector_math_64.dart' as vector_math_64; import 'package:zircon/zircon.dart'; @@ -59,6 +60,7 @@ class TestApp { final bool showOverlay; final bool hitTestable; final bool focusable; + final _responseListener = test_touch.TouchInputListenerProxy(); Color _backgroundColor = _blue; @@ -73,12 +75,7 @@ class TestApp { childView.create(hitTestable, focusable, (ByteData reply) { // Set up window allbacks. window.onPointerDataPacket = (PointerDataPacket packet) { - for (final data in packet.data) { - if (data.change == PointerChange.down) { - this._backgroundColor = _black; - } - } - window.scheduleFrame(); + this.pointerDataPacket(packet); }; window.onMetricsChanged = () { window.scheduleFrame(); @@ -159,6 +156,38 @@ class TestApp { window.render(sceneBuilder.build()); } + + void pointerDataPacket(PointerDataPacket packet) async { + int nowNanos = System.clockGetMonotonic(); + + for (PointerData data in packet.data) { + print('parent-view received tap: ${data.toStringFull()}'); + + if (data.change == PointerChange.down) { + this._backgroundColor = _black; + } + + if (data.change == PointerChange.down || data.change == PointerChange.move) { + Incoming.fromSvcPath() + ..connectToService(_responseListener) + ..close(); + + _respond(test_touch.TouchInputListenerReportTouchInputRequest( + localX: data.physicalX, + localY: data.physicalY, + timeReceived: nowNanos, + componentName: 'parent-view', + )); + } + } + + window.scheduleFrame(); + } + + void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async { + print('parent-view reporting touch input to TouchInputListener'); + await _responseListener.reportTouchInput(request); + } } class ChildView { diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml index 3eda9427a29c9..7cb17b79dd2fd 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml @@ -19,6 +19,8 @@ { protocol: [ "fuchsia.ui.app.ViewProvider", + "fuchsia.ui.test.input.TouchInputListener", + "fuchsia.ui.scenic.Scenic", ], }, { diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn index 83075b1a5cd54..643b41f6cd2ca 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn @@ -46,10 +46,15 @@ executable("touch-input-test-bin") { "$fuchsia_sdk_root/pkg:scenic_cpp", "$fuchsia_sdk_root/pkg:sys_component_cpp_testing", "$fuchsia_sdk_root/pkg:zx", + "embedding-flutter-view:package", "touch-input-view:package", "//build/fuchsia/fidl:fuchsia.ui.gfx", "//flutter/fml", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:portable_ui_test", + "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view:package", + "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view:package", + "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:color", + "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:screenshot", "//third_party/googletest:gtest", "//third_party/googletest:gtest_main", ] diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/README.md b/shell/platform/fuchsia/flutter/tests/integration/touch-input/README.md index 1d37bde6dc7b2..227c4ad84e229 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/README.md +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/README.md @@ -1,8 +1,9 @@ # touch-input `touch-input-test` exercises touch through a child view (in this case, the `touch-input-view` Dart component) and asserting -the precise location of the touch event. We do this by attaching the child view, injecting touch, and validating that the view -reports the touch event back with the correct coordinates. +the precise location of the touch event. We validate a touch event as valid through two ways: +- By attaching the child view, injecting touch, and validating that the view reports the touch event back with the correct coordinates. +- By embedding a child view into a parent view, injecting touch into both views, and validating that each view reports its touch event back with the correct coordinates. ```shell Injecting the tap event diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn new file mode 100644 index 0000000000000..7064427b2e98d --- /dev/null +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/fuchsia/sdk.gni") +import("//flutter/tools/fuchsia/dart/dart_library.gni") +import("//flutter/tools/fuchsia/flutter/flutter_component.gni") +import("//flutter/tools/fuchsia/gn-sdk/component.gni") +import("//flutter/tools/fuchsia/gn-sdk/package.gni") + +dart_library("lib") { + package_name = "embedding-flutter-view" + sources = [ "embedding-flutter-view.dart" ] + + deps = [ + "//flutter/shell/platform/fuchsia/dart:vector_math", + "//flutter/tools/fuchsia/dart:fuchsia_services", + "//flutter/tools/fuchsia/dart:zircon", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.scenic", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", + ] +} + +flutter_component("component") { + testonly = true + component_name = "embedding-flutter-view" + manifest = rebase_path("meta/embedding-flutter-view.cml") + main_package = "embedding-flutter-view" + main_dart = "embedding-flutter-view.dart" + + deps = [ ":lib" ] +} + +fuchsia_package("package") { + testonly = true + package_name = "embedding-flutter-view" + + deps = [ ":component" ] +} diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart new file mode 100644 index 0000000000000..eede613963e62 --- /dev/null +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart @@ -0,0 +1,176 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:typed_data'; +import 'dart:io'; +import 'dart:ui'; + +import 'package:fidl_fuchsia_ui_app/fidl_async.dart'; +import 'package:fidl_fuchsia_ui_views/fidl_async.dart'; +import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; +import 'package:fuchsia_services/services.dart'; +import 'package:vector_math/vector_math_64.dart' as vector_math_64; +import 'package:zircon/zircon.dart'; + +void main(List args) { + print('Launching embedding-flutter-view'); + TestApp app = TestApp(ChildView.gfx(_launchGfxChildView())); + app.run(); +} + +class TestApp { + static const _black = Color.fromARGB(255, 0, 0, 0); + static const _blue = Color.fromARGB(255, 0, 0, 255); + + final ChildView childView; + final _responseListener = test_touch.TouchInputListenerProxy(); + + Color _backgroundColor = _blue; + + TestApp(this.childView) {} + + void run() { + childView.create((ByteData reply) { + // Set up window callbacks. + window.onPointerDataPacket = (PointerDataPacket packet) { + this.pointerDataPacket(packet); + }; + window.onMetricsChanged = () { + window.scheduleFrame(); + }; + window.onBeginFrame = (Duration duration) { + this.beginFrame(duration); + }; + + // The child view should be attached to Scenic now. + // Ready to build the scene. + window.scheduleFrame(); + }); + } + + void beginFrame(Duration duration) { + // Convert physical screen size of device to values + final pixelRatio = window.devicePixelRatio; + final size = window.physicalSize / pixelRatio; + final physicalBounds = Offset.zero & window.physicalSize; + final windowBounds = Offset.zero & size; + // Set up a Canvas that uses the screen size + final recorder = PictureRecorder(); + final canvas = Canvas(recorder, physicalBounds); + canvas.scale(pixelRatio); + // Draw something + final paint = Paint()..color = this._backgroundColor; + canvas.drawRect(windowBounds, paint); + final picture = recorder.endRecording(); + // Build the scene + final sceneBuilder = SceneBuilder() + ..pushClipRect(physicalBounds) + ..addPicture(Offset.zero, picture); + // Child view should take up half the screen + final childPhysicalSize = window.physicalSize * 0.5; + sceneBuilder + ..addPlatformView(childView.viewId, + width: childPhysicalSize.width, + height: size.height) + ..pop(); + sceneBuilder.pop(); + window.render(sceneBuilder.build()); + } + + void pointerDataPacket(PointerDataPacket packet) async { + int nowNanos = System.clockGetMonotonic(); + + for (PointerData data in packet.data) { + print('embedding-flutter-view received tap: ${data.toStringFull()}'); + + if (data.change == PointerChange.down) { + this._backgroundColor = _black; + } + + if (data.change == PointerChange.down || data.change == PointerChange.move) { + Incoming.fromSvcPath() + ..connectToService(_responseListener) + ..close(); + + _respond(test_touch.TouchInputListenerReportTouchInputRequest( + localX: data.physicalX, + localY: data.physicalY, + timeReceived: nowNanos, + componentName: 'embedding-flutter-view', + )); + } + } + + window.scheduleFrame(); + } + + void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async { + print('embedding-flutter-view reporting touch input to TouchInputListener'); + await _responseListener.reportTouchInput(request); + } +} + +class ChildView { + final ViewHolderToken viewHolderToken; + final ViewportCreationToken viewportCreationToken; + final int viewId; + + ChildView(this.viewportCreationToken) : viewHolderToken = null, viewId = viewportCreationToken.value.handle.handle { + assert(viewId != null); + } + + ChildView.gfx(this.viewHolderToken) : viewportCreationToken = null, viewId = viewHolderToken.value.handle.handle { + assert(viewId != null); + } + + void create(PlatformMessageResponseCallback callback) { + // Construct the dart:ui platform message to create the view, and when the + // return callback is invoked, build the scene. At that point, it is safe + // to embed the child view in the scene. + final viewOcclusionHint = Rect.zero; + final Map args = { + 'viewId': viewId, + 'hitTestable': true, + 'focusable': true, + 'viewOcclusionHintLTRB': [ + viewOcclusionHint.left, + viewOcclusionHint.top, + viewOcclusionHint.right, + viewOcclusionHint.bottom + ], + }; + + final ByteData createViewMessage = utf8.encoder.convert( + json.encode({ + 'method': 'View.create', + 'args': args, + }) + ).buffer.asByteData(); + + final platformViewsChannel = 'flutter/platform_views'; + + PlatformDispatcher.instance.sendPlatformMessage( + platformViewsChannel, + createViewMessage, + callback); + } +} + +ViewHolderToken _launchGfxChildView() { + ViewProviderProxy viewProvider = ViewProviderProxy(); + Incoming.fromSvcPath() + ..connectToService(viewProvider) + ..close(); + + final viewTokens = EventPairPair(); + assert(viewTokens.status == ZX.OK); + final viewHolderToken = ViewHolderToken(value: viewTokens.first); + final viewToken = ViewToken(value: viewTokens.second); + + viewProvider.createView(viewToken.value, null, null); + viewProvider.ctrl.close(); + + return viewHolderToken; +} diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/meta/embedding-flutter-view.cml b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/meta/embedding-flutter-view.cml new file mode 100644 index 0000000000000..f55ac3507b2c8 --- /dev/null +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/meta/embedding-flutter-view.cml @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +{ + include: [ "syslog/client.shard.cml" ], + program: { + data: "data/embedding-flutter-view", + + // Always use the jit runner for now. + // TODO(fxbug.dev/106577): Implement manifest merging build rules for V2 components. + runner: "flutter_jit_runner", + }, + capabilities: [ + { + protocol: [ "fuchsia.ui.app.ViewProvider" ], + }, + ], + expose: [ + { + protocol: [ "fuchsia.ui.app.ViewProvider" ], + from: "self", + }, + ], + use: [ + { + protocol: [ + "fuchsia.ui.app.ViewProvider", + "fuchsia.ui.scenic.Scenic", + "fuchsia.ui.test.input.TouchInputListener", + ] + }, + { + directory: "config-data", + rights: [ "r*" ], + path: "/config/data", + }, + ] +} diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc index 78137ac0f49fd..4e440e923eadd 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc @@ -46,7 +46,9 @@ #include #include "flutter/fml/logging.h" +#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/color.h" #include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h" +#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/screenshot.h" // This test exercises the touch input dispatch path from Input Pipeline to a // Scenic client. It is a multi-component test, and carefully avoids sleeping or @@ -126,14 +128,24 @@ using RealmBuilder = component_testing::RealmBuilder; // Max timeout in failure cases. // Set this as low as you can that still works across all test platforms. -constexpr zx::duration kTimeout = zx::min(5); +constexpr zx::duration kTimeout = zx::min(1); +// Timeout for Scenic's |TakeScreenshot| FIDL call. +constexpr zx::duration kScreenshotTimeout = zx::sec(10); + +constexpr auto kTestUIStackUrl = + "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/test-ui-stack.cm"; constexpr auto kMockTouchInputListener = "touch_input_listener"; constexpr auto kMockTouchInputListenerRef = ChildRef{kMockTouchInputListener}; + constexpr auto kTouchInputView = "touch-input-view"; constexpr auto kTouchInputViewRef = ChildRef{kTouchInputView}; constexpr auto kTouchInputViewUrl = "fuchsia-pkg://fuchsia.com/touch-input-view#meta/touch-input-view.cm"; +constexpr auto kEmbeddingFlutterView = "embedding-flutter-view"; +constexpr auto kEmbeddingFlutterViewRef = ChildRef{kEmbeddingFlutterView}; +constexpr auto kEmbeddingFlutterViewUrl = + "fuchsia-pkg://fuchsia.com/embedding-flutter-view#meta/embedding-flutter-view.cm"; bool CompareDouble(double f0, double f1, double epsilon) { return std::abs(f0 - f1) <= epsilon; @@ -195,11 +207,11 @@ class TouchInputListenerServer events_received_; }; -class FlutterTapTest : public PortableUITest, +class FlutterTapTestBase : public PortableUITest, public ::testing::Test, public ::testing::WithParamInterface { protected: - ~FlutterTapTest() override { + ~FlutterTapTestBase() override { FML_CHECK(touch_injection_request_count() > 0) << "Injection expected but didn't happen."; } @@ -215,22 +227,6 @@ class FlutterTapTest : public PortableUITest, << "\n\n>> Test did not complete in time, terminating. <<\n\n"; }, kTimeout); - - // Get the display dimensions. - FML_LOG(INFO) << "Waiting for scenic display info"; - scenic_ = realm_root()->template Connect(); - scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { - display_width_ = display_info.width_in_px; - display_height_ = display_info.height_in_px; - FML_LOG(INFO) << "Got display_width = " << display_width_ - << " and display_height = " << display_height_; - }); - RunLoopUntil( - [this] { return display_width_ != 0 && display_height_ != 0; }); - - // Register input injection device. - FML_LOG(INFO) << "Registering input injection device"; - RegisterTouchScreen(); } bool LastEventReceivedMatches(float expected_x, @@ -251,56 +247,132 @@ class FlutterTapTest : public PortableUITest, auto actual_x = pixel_scale * last_event.local_x(); auto actual_y = pixel_scale * last_event.local_y(); + auto actual_component = last_event.component_name(); - FML_LOG(INFO) << "Expecting event for component " << component_name - << " at (" << expected_x << ", " << expected_y << ")"; - FML_LOG(INFO) << "Received event for component " << component_name - << " at (" << actual_x << ", " << actual_y - << "), accounting for pixel scale of " << pixel_scale; - - return CompareDouble(actual_x, expected_x, pixel_scale) && + bool last_event_matches = CompareDouble(actual_x, expected_x, pixel_scale) && CompareDouble(actual_y, expected_y, pixel_scale) && last_event.component_name() == component_name; + + if (last_event_matches) { + FML_LOG(INFO) << "Received event for component " << component_name + << " at (" << expected_x << ", " << expected_y << ")"; + } else { + FML_LOG(WARNING) << "Expecting event for component " << component_name + << " at (" << expected_x << ", " << expected_y << "). " + << "Instead received event for component " << actual_component + << " at (" << actual_x << ", " << actual_y + << "), accounting for pixel scale of " << pixel_scale; + } + + return last_event_matches; } // Guaranteed to be initialized after SetUp(). uint32_t display_width() const { return display_width_; } uint32_t display_height() const { return display_height_; } - private: - void ExtendRealm() override { - // Key part of service setup: have this test component vend the - // |TouchInputListener| service in the constructed realm. - touch_input_listener_server_ = - std::make_unique(dispatcher()); - realm_builder()->AddLocalChild(kMockTouchInputListener, - touch_input_listener_server_.get()); - - realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, - component_testing::ChildOptions{ - .environment = kFlutterRunnerEnvironment, - }); - - // Route the TouchInput protocol capability to the Dart component - realm_builder()->AddRoute( - Route{.capabilities = {Protocol{ - fuchsia::ui::test::input::TouchInputListener::Name_}}, - .source = kMockTouchInputListenerRef, - .targets = {kFlutterJitRunnerRef, kTouchInputViewRef}}); - - realm_builder()->AddRoute( - Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, - .source = kTouchInputViewRef, - .targets = {ParentRef()}}); - } - ParamType GetTestUIStackUrl() override { return GetParam(); }; std::unique_ptr touch_input_listener_server_; +}; + +class FlutterTapTest : public FlutterTapTestBase { + private: + void ExtendRealm() override { + FML_LOG(INFO) << "Extending realm"; + // Key part of service setup: have this test component vend the + // |TouchInputListener| service in the constructed realm. + touch_input_listener_server_ = + std::make_unique(dispatcher()); + realm_builder()->AddLocalChild(kMockTouchInputListener, + touch_input_listener_server_.get()); + + // Add touch-input-view to the Realm + realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + + // Route the TouchInput protocol capability to the Dart component + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{ + fuchsia::ui::test::input::TouchInputListener::Name_}}, + .source = kMockTouchInputListenerRef, + .targets = {kFlutterJitRunnerRef, kTouchInputViewRef}}); + + realm_builder()->AddRoute(Route{ + .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kTouchInputViewRef, + .targets = {ParentRef()}}); + } +}; - fuchsia::ui::scenic::ScenicPtr scenic_; - uint32_t display_width_ = 0; - uint32_t display_height_ = 0; +class FlutterEmbedTapTest : public FlutterTapTestBase { + protected: + // Takes a screenshot and waits for child view to embed itself to the parent view + bool WaitForEmbed() { + return RunLoopWithTimeoutOrUntil([this] { + constexpr fuchsia_test_utils::Color kChildBackgroundColor = { + 0xFF, 0x00, 0xFF, 0xFF}; // Pink + fuchsia::ui::scenic::ScreenshotData screenshot_out; + scenic_->TakeScreenshot( + [this, &screenshot_out]( + fuchsia::ui::scenic::ScreenshotData screenshot, bool status) { + EXPECT_TRUE(status) << "Failed to take screenshot"; + screenshot_out = std::move(screenshot); + QuitLoop(); + }); + EXPECT_FALSE(RunLoopWithTimeout(kScreenshotTimeout)) + << "Timed out waiting for screenshot."; + + auto screenshot = fuchsia_test_utils::Screenshot(screenshot_out); + auto histogram = screenshot.Histogram(); + + bool color_found = histogram[kChildBackgroundColor] > 0; + return color_found; + }, + kTimeout); + } + + private: + void ExtendRealm() override { + FML_LOG(INFO) << "Extending realm"; + // Key part of service setup: have this test component vend the + // |TouchInputListener| service in the constructed realm. + touch_input_listener_server_ = + std::make_unique(dispatcher()); + realm_builder()->AddLocalChild(kMockTouchInputListener, + touch_input_listener_server_.get()); + + // Add touch-input-view to the Realm + realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + // Add embedding-flutter-view to the Realm + // This component will embed touch-input-view as a child view + realm_builder()->AddChild(kEmbeddingFlutterView, kEmbeddingFlutterViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + + // Route the TouchInput protocol capability to the Dart component + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{ + fuchsia::ui::test::input::TouchInputListener::Name_}}, + .source = kMockTouchInputListenerRef, + .targets = {kFlutterJitRunnerRef, kTouchInputViewRef, + kEmbeddingFlutterViewRef}}); + + realm_builder()->AddRoute(Route{ + .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kEmbeddingFlutterViewRef, + .targets = {ParentRef()}}); + realm_builder()->AddRoute(Route{ + .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kTouchInputViewRef, + .targets = {kEmbeddingFlutterViewRef}}); + } }; // Makes use of gtest's parameterized testing, allowing us @@ -310,9 +382,7 @@ class FlutterTapTest : public PortableUITest, INSTANTIATE_TEST_SUITE_P( FlutterTapTestParameterized, FlutterTapTest, - ::testing::Values( - "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/" - "test-ui-stack.cm")); + ::testing::Values(kTestUIStackUrl)); TEST_P(FlutterTapTest, FlutterTap) { // Launch client view, and wait until it's rendering to proceed with the test. @@ -335,5 +405,47 @@ TEST_P(FlutterTapTest, FlutterTap) { }); } +INSTANTIATE_TEST_SUITE_P( + FlutterEmbedTapTestParameterized, + FlutterEmbedTapTest, + ::testing::Values(kTestUIStackUrl)); + +TEST_P(FlutterEmbedTapTest, FlutterEmbedTap) { + // Launch view + FML_LOG(INFO) << "Initializing scene"; + LaunchClient(); + FML_LOG(INFO) << "Client launched"; + // Wait for child view to embed and render to proceed with the test. + WaitForEmbed(); + FML_LOG(INFO) << "Embedded child view has rendered"; + + { + // Embedded child view takes up the left side of the screen + // Expect a response from the child view if we inject a tap there + InjectTap(-500, -500); + RunLoopUntil([this] { + return LastEventReceivedMatches( + /*expected_x=*/static_cast(display_width() / 4.0f), + /*expected_y=*/static_cast(display_height() / 4.0f), + /*component_name=*/"touch-input-view"); + }); + } + + { + // Parent view takes up the right side of the screen + // Validate that parent can still receive taps + InjectTap(500, 500); + RunLoopUntil([this] { + return LastEventReceivedMatches( + /*expected_x=*/static_cast(display_width() / (4.0f / 3.0f)), + /*expected_y=*/static_cast(display_height() / (4.0f / 3.0f)), + /*component_name=*/"embedding-flutter-view"); + }); + } + + // There should be 2 injected taps + ASSERT_EQ(touch_injection_request_count(), 2); +} + } // namespace } // namespace touch_input_test::testing diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/lib/touch-input-view.dart b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/lib/touch-input-view.dart index 3578ae93a6a05..58c1ac98edbad 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/lib/touch-input-view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/lib/touch-input-view.dart @@ -11,30 +11,17 @@ import 'package:fuchsia_services/services.dart'; import 'package:zircon/zircon.dart'; void main() { - print('Launching two-flutter view'); - MyApp app = MyApp(); + print('Launching touch-input-view'); + TestApp app = TestApp(); app.run(); } -class MyApp { - static const _red = Color.fromARGB(255, 244, 67, 54); - static const _orange = Color.fromARGB(255, 255, 152, 0); - static const _yellow = Color.fromARGB(255, 255, 235, 59); - static const _green = Color.fromARGB(255, 76, 175, 80); - static const _blue = Color.fromARGB(255, 33, 150, 143); - static const _purple = Color.fromARGB(255, 156, 39, 176); +class TestApp { + static const _yellow = Color.fromARGB(255, 255, 255, 0); + static const _pink = Color.fromARGB(255, 255, 0, 255); - final List _colors = [ - _red, - _orange, - _yellow, - _green, - _blue, - _purple, - ]; + Color _backgroundColor = _pink; - // Each tap will increment the counter, we then determine what color to choose - int _touchCounter = 0; final _responseListener = test_touch.TouchInputListenerProxy(); void run() { @@ -59,15 +46,14 @@ class MyApp { final pixelRatio = window.devicePixelRatio; final size = window.physicalSize / pixelRatio; final physicalBounds = Offset.zero & size * pixelRatio; - // Set up Canvas that uses the screen size + final windowBounds = Offset.zero & size; + // Set up a Canvas that uses the screen size final recorder = PictureRecorder(); final canvas = Canvas(recorder, physicalBounds); canvas.scale(pixelRatio, pixelRatio); // Draw something - // Color of the screen is set initially to the first value in _colors - // Incrementing _touchCounter will change screen color - final paint = Paint()..color = _colors[_touchCounter % _colors.length]; - canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint); + final paint = Paint()..color = this._backgroundColor; + canvas.drawRect(windowBounds, paint); // Build the scene final picture = recorder.endRecording(); final sceneBuilder = SceneBuilder() @@ -83,10 +69,6 @@ class MyApp { for (PointerData data in packet.data) { print('touch-input-view received tap: ${data.toStringFull()}'); - if (data.change == PointerChange.down) { - _touchCounter++; - } - if (data.change == PointerChange.down || data.change == PointerChange.move) { Incoming.fromSvcPath() ..connectToService(_responseListener) diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/meta/touch-input-view.cml b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/meta/touch-input-view.cml index bdd76ea1b30ee..0210fbd527a55 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/meta/touch-input-view.cml +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/meta/touch-input-view.cml @@ -24,11 +24,7 @@ use: [ { protocol: [ - "fuchsia.sysmem.Allocator", - "fuchsia.tracing.provider.Registry", - "fuchsia.ui.scenic.Scenic", "fuchsia.ui.test.input.TouchInputListener", - "fuchsia.vulkan.loader.Loader", ] } ] diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc index 86a3147f9f63c..dd663fb75cdc0 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc @@ -31,10 +31,7 @@ using fuchsia_test_utils::CheckViewExistsInSnapshot; void PortableUITest::SetUp() { SetUpRealmBase(); - ExtendRealm(); - - realm_ = std::make_unique(realm_builder_.Build()); } void PortableUITest::SetUpRealmBase() { @@ -139,15 +136,31 @@ void PortableUITest::WatchViewGeometry() { }); } -bool PortableUITest::HasViewConnected(zx_koid_t view_ref_koid) { - return last_view_tree_snapshot_.has_value() && - CheckViewExistsInSnapshot(*last_view_tree_snapshot_, view_ref_koid); +bool PortableUITest::HasViewConnected( + fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, + std::optional& watch_response, + zx_koid_t view_ref_koid) { + std::optional watch_result; + view_tree_watcher->Watch( + [&watch_result](auto response) { watch_result = std::move(response); }); + FML_LOG(INFO) << "Waiting for view tree watch result"; + RunLoopUntil([&watch_result] { return watch_result.has_value(); }); + FML_LOG(INFO) << "Received for view tree watch result"; + if (CheckViewExistsInUpdates(watch_result->updates(), view_ref_koid)) { + watch_response = std::move(watch_result); + }; + return watch_response.has_value(); } void PortableUITest::LaunchClient() { + realm_ = std::make_unique(realm_builder_.Build()); + + RegisterTouchScreen(); + scene_provider_ = realm_->Connect(); scene_provider_.set_error_handler( [](auto) { FML_LOG(ERROR) << "Error from test scene provider"; }); + fuchsia::ui::test::scene::ControllerAttachClientViewRequest request; request.set_view_provider(realm_->Connect()); scene_provider_->RegisterViewTreeWatcher(view_tree_watcher_.NewRequest(), @@ -160,12 +173,27 @@ void PortableUITest::LaunchClient() { FML_LOG(INFO) << "Waiting for client view ref koid"; RunLoopUntil([this] { return client_root_view_ref_koid_.has_value(); }); - WatchViewGeometry(); - FML_LOG(INFO) << "Waiting for client view to connect"; - RunLoopUntil( - [this] { return HasViewConnected(*client_root_view_ref_koid_); }); + // Wait for the client view to get attached to the view tree. + std::optional watch_response; + RunLoopUntil([this, &watch_response] { + return HasViewConnected(view_tree_watcher_, watch_response, + *client_root_view_ref_koid_); + }); FML_LOG(INFO) << "Client view has rendered"; + + scenic_ = realm_->Connect(); + FML_LOG(INFO) << "Launched parent view"; + + // Get the display dimensions. + FML_LOG(INFO) << "Waiting for scenic display info"; + scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { + display_width_ = display_info.width_in_px; + display_height_ = display_info.height_in_px; + FML_LOG(INFO) << "Got display_width = " << display_width_ + << " and display_height = " << display_height_; + }); + RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; }); } void PortableUITest::RegisterTouchScreen() { diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h index 55afc990dd0bf..65d4c313b57d0 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h @@ -51,7 +51,10 @@ class PortableUITest : public ::loop_fixture::RealLoop { // Returns true when the specified view is fully connected to the scene AND // has presented at least one frame of content. - bool HasViewConnected(zx_koid_t view_ref_koid); + bool HasViewConnected( + fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, + std::optional& watch_response, + zx_koid_t view_ref_koid); // Registers a fake touch screen device with an injection coordinate space // spanning [-1000, 1000] on both axes. @@ -63,6 +66,10 @@ class PortableUITest : public ::loop_fixture::RealLoop { protected: component_testing::RealmBuilder* realm_builder() { return &realm_builder_; } component_testing::RealmRoot* realm_root() { return realm_.get(); } + + fuchsia::ui::scenic::ScenicPtr scenic_; + uint32_t display_width_ = 0; + uint32_t display_height_ = 0; int touch_injection_request_count() const { return touch_injection_request_count_; diff --git a/tools/fuchsia/devshell/run_integration_test.sh b/tools/fuchsia/devshell/run_integration_test.sh index f3b86ad9130e7..7b31a3a9f45af 100755 --- a/tools/fuchsia/devshell/run_integration_test.sh +++ b/tools/fuchsia/devshell/run_integration_test.sh @@ -60,7 +60,7 @@ case $test_name in test_packages=("text-input-test-0.far" "text-input-view.far") ;; touch-input) - test_packages=("touch-input-test-0.far" "touch-input-view.far") + test_packages=("touch-input-test-0.far" "touch-input-view.far" "embedding-flutter-view.far") ;; *) engine-error "Unknown test name $test_name. You may need to add it to $0" From 2c47faba0ac82c0e04965da281c9c96200c40804 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 20:15:23 +0000 Subject: [PATCH 2/9] Lint CC files --- .../embedder/flutter-embedder-test.cc | 6 +- .../touch-input/touch-input-test.cc | 226 +++++++++--------- .../integration/utils/portable_ui_test.cc | 6 +- .../integration/utils/portable_ui_test.h | 7 +- 4 files changed, 127 insertions(+), 118 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc index 557f917903a81..6f94efc30afe8 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc @@ -480,7 +480,8 @@ void FlutterEmbedderTest::TryInject(int32_t x, int32_t y) { // ASSERT_TRUE(TakeScreenshotUntil( // kChildBackgroundColor, // [](std::map histogram) { -// // Expect parent and child background colors, with parent color > child +// // Expect parent and child background colors, with parent color > +// child // // color. // EXPECT_GT(histogram[kParentBackgroundColor], 0u); // EXPECT_GT(histogram[kChildBackgroundColor], 0u); @@ -525,7 +526,8 @@ TEST_F(FlutterEmbedderTest, HittestEmbedding) { // ASSERT_TRUE(TakeScreenshotUntil( // kParentTappedColor, // [](std::map histogram) { -// // Expect parent and child background colors, with parent color > child +// // Expect parent and child background colors, with parent color > +// child // // color. // EXPECT_EQ(histogram[kParentBackgroundColor], 0u); // EXPECT_GT(histogram[kParentTappedColor], 0u); diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc index 4e440e923eadd..97ac68ffbe809 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc @@ -133,7 +133,8 @@ constexpr zx::duration kTimeout = zx::min(1); constexpr zx::duration kScreenshotTimeout = zx::sec(10); constexpr auto kTestUIStackUrl = - "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/test-ui-stack.cm"; + "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/" + "test-ui-stack.cm"; constexpr auto kMockTouchInputListener = "touch_input_listener"; constexpr auto kMockTouchInputListenerRef = ChildRef{kMockTouchInputListener}; @@ -145,7 +146,8 @@ constexpr auto kTouchInputViewUrl = constexpr auto kEmbeddingFlutterView = "embedding-flutter-view"; constexpr auto kEmbeddingFlutterViewRef = ChildRef{kEmbeddingFlutterView}; constexpr auto kEmbeddingFlutterViewUrl = - "fuchsia-pkg://fuchsia.com/embedding-flutter-view#meta/embedding-flutter-view.cm"; + "fuchsia-pkg://fuchsia.com/embedding-flutter-view#meta/" + "embedding-flutter-view.cm"; bool CompareDouble(double f0, double f1, double epsilon) { return std::abs(f0 - f1) <= epsilon; @@ -208,8 +210,8 @@ class TouchInputListenerServer }; class FlutterTapTestBase : public PortableUITest, - public ::testing::Test, - public ::testing::WithParamInterface { + public ::testing::Test, + public ::testing::WithParamInterface { protected: ~FlutterTapTestBase() override { FML_CHECK(touch_injection_request_count() > 0) @@ -249,19 +251,21 @@ class FlutterTapTestBase : public PortableUITest, auto actual_y = pixel_scale * last_event.local_y(); auto actual_component = last_event.component_name(); - bool last_event_matches = CompareDouble(actual_x, expected_x, pixel_scale) && - CompareDouble(actual_y, expected_y, pixel_scale) && - last_event.component_name() == component_name; + bool last_event_matches = + CompareDouble(actual_x, expected_x, pixel_scale) && + CompareDouble(actual_y, expected_y, pixel_scale) && + last_event.component_name() == component_name; if (last_event_matches) { FML_LOG(INFO) << "Received event for component " << component_name << " at (" << expected_x << ", " << expected_y << ")"; } else { FML_LOG(WARNING) << "Expecting event for component " << component_name - << " at (" << expected_x << ", " << expected_y << "). " - << "Instead received event for component " << actual_component - << " at (" << actual_x << ", " << actual_y - << "), accounting for pixel scale of " << pixel_scale; + << " at (" << expected_x << ", " << expected_y << "). " + << "Instead received event for component " + << actual_component << " at (" << actual_x << ", " + << actual_y << "), accounting for pixel scale of " + << pixel_scale; } return last_event_matches; @@ -277,112 +281,113 @@ class FlutterTapTestBase : public PortableUITest, }; class FlutterTapTest : public FlutterTapTestBase { - private: - void ExtendRealm() override { - FML_LOG(INFO) << "Extending realm"; - // Key part of service setup: have this test component vend the - // |TouchInputListener| service in the constructed realm. - touch_input_listener_server_ = - std::make_unique(dispatcher()); - realm_builder()->AddLocalChild(kMockTouchInputListener, - touch_input_listener_server_.get()); - - // Add touch-input-view to the Realm - realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, - component_testing::ChildOptions{ - .environment = kFlutterRunnerEnvironment, - }); - - // Route the TouchInput protocol capability to the Dart component - realm_builder()->AddRoute( - Route{.capabilities = {Protocol{ - fuchsia::ui::test::input::TouchInputListener::Name_}}, - .source = kMockTouchInputListenerRef, - .targets = {kFlutterJitRunnerRef, kTouchInputViewRef}}); - - realm_builder()->AddRoute(Route{ - .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, - .source = kTouchInputViewRef, - .targets = {ParentRef()}}); - } + private: + void ExtendRealm() override { + FML_LOG(INFO) << "Extending realm"; + // Key part of service setup: have this test component vend the + // |TouchInputListener| service in the constructed realm. + touch_input_listener_server_ = + std::make_unique(dispatcher()); + realm_builder()->AddLocalChild(kMockTouchInputListener, + touch_input_listener_server_.get()); + + // Add touch-input-view to the Realm + realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + + // Route the TouchInput protocol capability to the Dart component + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{ + fuchsia::ui::test::input::TouchInputListener::Name_}}, + .source = kMockTouchInputListenerRef, + .targets = {kFlutterJitRunnerRef, kTouchInputViewRef}}); + + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kTouchInputViewRef, + .targets = {ParentRef()}}); + } }; class FlutterEmbedTapTest : public FlutterTapTestBase { - protected: - // Takes a screenshot and waits for child view to embed itself to the parent view - bool WaitForEmbed() { - return RunLoopWithTimeoutOrUntil([this] { - constexpr fuchsia_test_utils::Color kChildBackgroundColor = { - 0xFF, 0x00, 0xFF, 0xFF}; // Pink - fuchsia::ui::scenic::ScreenshotData screenshot_out; - scenic_->TakeScreenshot( - [this, &screenshot_out]( - fuchsia::ui::scenic::ScreenshotData screenshot, bool status) { - EXPECT_TRUE(status) << "Failed to take screenshot"; - screenshot_out = std::move(screenshot); - QuitLoop(); - }); - EXPECT_FALSE(RunLoopWithTimeout(kScreenshotTimeout)) - << "Timed out waiting for screenshot."; - - auto screenshot = fuchsia_test_utils::Screenshot(screenshot_out); - auto histogram = screenshot.Histogram(); - - bool color_found = histogram[kChildBackgroundColor] > 0; - return color_found; - }, - kTimeout); - } + protected: + // Takes a screenshot and waits for child view to embed itself to the parent + // view + bool WaitForEmbed() { + return RunLoopWithTimeoutOrUntil( + [this] { + constexpr fuchsia_test_utils::Color kChildBackgroundColor = { + 0xFF, 0x00, 0xFF, 0xFF}; // Pink + fuchsia::ui::scenic::ScreenshotData screenshot_out; + scenic_->TakeScreenshot( + [this, &screenshot_out]( + fuchsia::ui::scenic::ScreenshotData screenshot, bool status) { + EXPECT_TRUE(status) << "Failed to take screenshot"; + screenshot_out = std::move(screenshot); + QuitLoop(); + }); + EXPECT_FALSE(RunLoopWithTimeout(kScreenshotTimeout)) + << "Timed out waiting for screenshot."; + + auto screenshot = fuchsia_test_utils::Screenshot(screenshot_out); + auto histogram = screenshot.Histogram(); + + bool color_found = histogram[kChildBackgroundColor] > 0; + return color_found; + }, + kTimeout); + } - private: - void ExtendRealm() override { - FML_LOG(INFO) << "Extending realm"; - // Key part of service setup: have this test component vend the - // |TouchInputListener| service in the constructed realm. - touch_input_listener_server_ = - std::make_unique(dispatcher()); - realm_builder()->AddLocalChild(kMockTouchInputListener, - touch_input_listener_server_.get()); - - // Add touch-input-view to the Realm - realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, - component_testing::ChildOptions{ - .environment = kFlutterRunnerEnvironment, - }); - // Add embedding-flutter-view to the Realm - // This component will embed touch-input-view as a child view - realm_builder()->AddChild(kEmbeddingFlutterView, kEmbeddingFlutterViewUrl, - component_testing::ChildOptions{ - .environment = kFlutterRunnerEnvironment, - }); - - // Route the TouchInput protocol capability to the Dart component - realm_builder()->AddRoute( - Route{.capabilities = {Protocol{ - fuchsia::ui::test::input::TouchInputListener::Name_}}, - .source = kMockTouchInputListenerRef, - .targets = {kFlutterJitRunnerRef, kTouchInputViewRef, - kEmbeddingFlutterViewRef}}); - - realm_builder()->AddRoute(Route{ - .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, - .source = kEmbeddingFlutterViewRef, - .targets = {ParentRef()}}); - realm_builder()->AddRoute(Route{ - .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, - .source = kTouchInputViewRef, - .targets = {kEmbeddingFlutterViewRef}}); - } + private: + void ExtendRealm() override { + FML_LOG(INFO) << "Extending realm"; + // Key part of service setup: have this test component vend the + // |TouchInputListener| service in the constructed realm. + touch_input_listener_server_ = + std::make_unique(dispatcher()); + realm_builder()->AddLocalChild(kMockTouchInputListener, + touch_input_listener_server_.get()); + + // Add touch-input-view to the Realm + realm_builder()->AddChild(kTouchInputView, kTouchInputViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + // Add embedding-flutter-view to the Realm + // This component will embed touch-input-view as a child view + realm_builder()->AddChild(kEmbeddingFlutterView, kEmbeddingFlutterViewUrl, + component_testing::ChildOptions{ + .environment = kFlutterRunnerEnvironment, + }); + + // Route the TouchInput protocol capability to the Dart component + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{ + fuchsia::ui::test::input::TouchInputListener::Name_}}, + .source = kMockTouchInputListenerRef, + .targets = {kFlutterJitRunnerRef, kTouchInputViewRef, + kEmbeddingFlutterViewRef}}); + + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kEmbeddingFlutterViewRef, + .targets = {ParentRef()}}); + realm_builder()->AddRoute( + Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}}, + .source = kTouchInputViewRef, + .targets = {kEmbeddingFlutterViewRef}}); + } }; // Makes use of gtest's parameterized testing, allowing us // to test different combinations of test-ui-stack + runners. Currently, there // is just one combination. Documentation: // http://go/gunitadvanced#value-parameterized-tests -INSTANTIATE_TEST_SUITE_P( - FlutterTapTestParameterized, - FlutterTapTest, - ::testing::Values(kTestUIStackUrl)); +INSTANTIATE_TEST_SUITE_P(FlutterTapTestParameterized, + FlutterTapTest, + ::testing::Values(kTestUIStackUrl)); TEST_P(FlutterTapTest, FlutterTap) { // Launch client view, and wait until it's rendering to proceed with the test. @@ -405,10 +410,9 @@ TEST_P(FlutterTapTest, FlutterTap) { }); } -INSTANTIATE_TEST_SUITE_P( - FlutterEmbedTapTestParameterized, - FlutterEmbedTapTest, - ::testing::Values(kTestUIStackUrl)); +INSTANTIATE_TEST_SUITE_P(FlutterEmbedTapTestParameterized, + FlutterEmbedTapTest, + ::testing::Values(kTestUIStackUrl)); TEST_P(FlutterEmbedTapTest, FlutterEmbedTap) { // Launch view diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc index dd663fb75cdc0..33ab95404e2fa 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc @@ -138,7 +138,8 @@ void PortableUITest::WatchViewGeometry() { bool PortableUITest::HasViewConnected( fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, - std::optional& watch_response, + std::optional& + watch_response, zx_koid_t view_ref_koid) { std::optional watch_result; view_tree_watcher->Watch( @@ -175,7 +176,8 @@ void PortableUITest::LaunchClient() { FML_LOG(INFO) << "Waiting for client view to connect"; // Wait for the client view to get attached to the view tree. - std::optional watch_response; + std::optional + watch_response; RunLoopUntil([this, &watch_response] { return HasViewConnected(view_tree_watcher_, watch_response, *client_root_view_ref_koid_); diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h index 65d4c313b57d0..c96206483d967 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h @@ -52,9 +52,10 @@ class PortableUITest : public ::loop_fixture::RealLoop { // Returns true when the specified view is fully connected to the scene AND // has presented at least one frame of content. bool HasViewConnected( - fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, - std::optional& watch_response, - zx_koid_t view_ref_koid); + fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, + std::optional& + watch_response, + zx_koid_t view_ref_koid); // Registers a fake touch screen device with an injection coordinate space // spanning [-1000, 1000] on both axes. From 80c76245ccebd95a8ffc6e9c5b226b53d2c3f29e Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 20:17:28 +0000 Subject: [PATCH 3/9] GN formatting --- .../tests/integration/embedder/child-view/lib/child_view.dart | 2 +- .../flutter/tests/integration/embedder/parent-view/BUILD.gn | 2 +- .../fuchsia/flutter/tests/integration/touch-input/BUILD.gn | 2 +- .../integration/touch-input/embedding-flutter-view/BUILD.gn | 2 +- .../fuchsia/flutter/tests/integration/utils/portable_ui_test.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart index f3d6f8835d951..40997c792a033 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart @@ -70,7 +70,7 @@ class TestApp { Incoming.fromSvcPath() ..connectToService(_responseListener) ..close(); - + _respond(test_touch.TouchInputListenerReportTouchInputRequest( localX: data.physicalX, localY: data.physicalY, diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn index 627c8467473b5..5fe18345e16b8 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn @@ -18,8 +18,8 @@ dart_library("lib") { "//flutter/tools/fuchsia/dart:zircon", "//flutter/tools/fuchsia/fidl:fuchsia.sys", "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", - "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn index 643b41f6cd2ca..f09b06f947885 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn @@ -50,10 +50,10 @@ executable("touch-input-test-bin") { "touch-input-view:package", "//build/fuchsia/fidl:fuchsia.ui.gfx", "//flutter/fml", - "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:portable_ui_test", "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view:package", "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view:package", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:color", + "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:portable_ui_test", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:screenshot", "//third_party/googletest:gtest", "//third_party/googletest:gtest_main", diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn index 7064427b2e98d..e291e50fb1dba 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn @@ -16,10 +16,10 @@ dart_library("lib") { "//flutter/shell/platform/fuchsia/dart:vector_math", "//flutter/tools/fuchsia/dart:fuchsia_services", "//flutter/tools/fuchsia/dart:zircon", - "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", "//flutter/tools/fuchsia/fidl:fuchsia.ui.scenic", "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", + "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h index c96206483d967..174cc01793a08 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h @@ -67,7 +67,7 @@ class PortableUITest : public ::loop_fixture::RealLoop { protected: component_testing::RealmBuilder* realm_builder() { return &realm_builder_; } component_testing::RealmRoot* realm_root() { return realm_.get(); } - + fuchsia::ui::scenic::ScenicPtr scenic_; uint32_t display_width_ = 0; uint32_t display_height_ = 0; From 88334b7583c70db1042cb9e977a8c1b0317889ed Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 20:24:44 +0000 Subject: [PATCH 4/9] Remove changes to embedder --- .../integration/embedder/child-view/BUILD.gn | 7 - .../embedder/child-view/lib/child_view.dart | 33 +-- .../embedder/child-view/meta/child-view.cml | 7 - .../embedder/flutter-embedder-test.cc | 222 +++++++++--------- .../integration/embedder/parent-view/BUILD.gn | 1 - .../embedder/parent-view/lib/parent_view.dart | 41 +--- .../embedder/parent-view/meta/parent-view.cml | 2 - 7 files changed, 117 insertions(+), 196 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn index 1601a7c02f34d..dedf77c3eb950 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/BUILD.gn @@ -10,13 +10,6 @@ import("//flutter/tools/fuchsia/gn-sdk/package.gni") dart_library("lib") { package_name = "child-view" sources = [ "child_view.dart" ] - - deps = [ - "//flutter/shell/platform/fuchsia/dart:args", - "//flutter/tools/fuchsia/dart:fuchsia_services", - "//flutter/tools/fuchsia/dart:zircon", - "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", - ] } flutter_component("component") { diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart index 40997c792a033..5b71294b700d5 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/lib/child_view.dart @@ -2,14 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:typed_data'; import 'dart:ui'; -import 'package:args/args.dart'; -import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; -import 'package:fuchsia_services/services.dart'; -import 'package:zircon/zircon.dart'; - void main(List args) { print('child-view: starting'); @@ -23,8 +17,6 @@ class TestApp { Color _backgroundColor = _pink; - final _responseListener = test_touch.TouchInputListenerProxy(); - void run() { window.onPointerDataPacket = (PointerDataPacket packet) { this.pointerDataPacket(packet); @@ -57,34 +49,11 @@ class TestApp { } void pointerDataPacket(PointerDataPacket packet) { - int nowNanos = System.clockGetMonotonic(); - - for (PointerData data in packet.data) { - print('child-view received tap: ${data.toStringFull()}'); - + for (final data in packet.data) { if (data.change == PointerChange.down) { this._backgroundColor = _yellow; } - - if (data.change == PointerChange.down || data.change == PointerChange.move) { - Incoming.fromSvcPath() - ..connectToService(_responseListener) - ..close(); - - _respond(test_touch.TouchInputListenerReportTouchInputRequest( - localX: data.physicalX, - localY: data.physicalY, - timeReceived: nowNanos, - componentName: 'child-view', - )); - } } - window.scheduleFrame(); } - - void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async { - print('child-view reporting touch input to TouchInputListener'); - await _responseListener.reportTouchInput(request); - } } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml index a70ee8d30eeb3..c1aab3a83d063 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view/meta/child-view.cml @@ -21,11 +21,4 @@ from: "self", }, ], - use: [ - { - protocol: [ - "fuchsia.ui.test.input.TouchInputListener", - ] - } - ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc index 6f94efc30afe8..20200e0725c58 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/flutter-embedder-test.cc @@ -86,36 +86,36 @@ constexpr auto kTestUiStackRef = ChildRef{kTestUiStack}; constexpr fuchsia_test_utils::Color kParentBackgroundColor = {0x00, 0x00, 0xFF, 0xFF}; // Blue -// constexpr fuchsia_test_utils::Color kParentTappedColor = {0x00, 0x00, 0x00, -// 0xFF}; // Black +constexpr fuchsia_test_utils::Color kParentTappedColor = {0x00, 0x00, 0x00, + 0xFF}; // Black constexpr fuchsia_test_utils::Color kChildBackgroundColor = {0xFF, 0x00, 0xFF, 0xFF}; // Pink constexpr fuchsia_test_utils::Color kChildTappedColor = {0xFF, 0xFF, 0x00, 0xFF}; // Yellow // TODO(fxb/64201): Remove forced opacity colors when Flatland is enabled. -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor1 = { -// 0x00, 0xFF, 0x0E, 0xFF}; // Green, blended with blue (FEMU local) -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor2 = { -// 0x0E, 0xFF, 0x0E, 0xFF}; // Green, blended with pink (FEMU local) -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor3 = { -// 0x00, 0xFF, 0x0D, 0xFF}; // Green, blended with blue (AEMU infra) -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor4 = { -// 0x0D, 0xFF, 0x0D, 0xFF}; // Green, blended with pink (AEMU infra) -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor5 = { -// 0x00, 0xFE, 0x0D, 0xFF}; // Green, blended with blue (NUC) -// constexpr fuchsia_test_utils::Color kOverlayBackgroundColor6 = { -// 0x0D, 0xFF, 0x00, 0xFF}; // Green, blended with pink (NUC) - -// static size_t OverlayPixelCount( -// std::map& histogram) { -// return histogram[kOverlayBackgroundColor1] + -// histogram[kOverlayBackgroundColor2] + -// histogram[kOverlayBackgroundColor3] + -// histogram[kOverlayBackgroundColor4] + -// histogram[kOverlayBackgroundColor5] + -// histogram[kOverlayBackgroundColor6]; -// } +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor1 = { + 0x00, 0xFF, 0x0E, 0xFF}; // Green, blended with blue (FEMU local) +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor2 = { + 0x0E, 0xFF, 0x0E, 0xFF}; // Green, blended with pink (FEMU local) +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor3 = { + 0x00, 0xFF, 0x0D, 0xFF}; // Green, blended with blue (AEMU infra) +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor4 = { + 0x0D, 0xFF, 0x0D, 0xFF}; // Green, blended with pink (AEMU infra) +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor5 = { + 0x00, 0xFE, 0x0D, 0xFF}; // Green, blended with blue (NUC) +constexpr fuchsia_test_utils::Color kOverlayBackgroundColor6 = { + 0x0D, 0xFF, 0x00, 0xFF}; // Green, blended with pink (NUC) + +static size_t OverlayPixelCount( + std::map& histogram) { + return histogram[kOverlayBackgroundColor1] + + histogram[kOverlayBackgroundColor2] + + histogram[kOverlayBackgroundColor3] + + histogram[kOverlayBackgroundColor4] + + histogram[kOverlayBackgroundColor5] + + histogram[kOverlayBackgroundColor6]; +} // Timeout for Scenic's |TakeScreenshot| FIDL call. constexpr zx::duration kScreenshotTimeout = zx::sec(10); @@ -473,22 +473,21 @@ void FlutterEmbedderTest::TryInject(int32_t x, int32_t y) { dispatcher(), [this, x, y] { TryInject(x, y); }, kTapRetryInterval); } -// TEST_F(FlutterEmbedderTest, Embedding) { -// LaunchParentViewInRealm(); - -// // Take screenshot until we see the child-view's embedded color. -// ASSERT_TRUE(TakeScreenshotUntil( -// kChildBackgroundColor, -// [](std::map histogram) { -// // Expect parent and child background colors, with parent color > -// child -// // color. -// EXPECT_GT(histogram[kParentBackgroundColor], 0u); -// EXPECT_GT(histogram[kChildBackgroundColor], 0u); -// EXPECT_GT(histogram[kParentBackgroundColor], -// histogram[kChildBackgroundColor]); -// })); -// } +TEST_F(FlutterEmbedderTest, Embedding) { + LaunchParentViewInRealm(); + + // Take screenshot until we see the child-view's embedded color. + ASSERT_TRUE(TakeScreenshotUntil( + kChildBackgroundColor, + [](std::map histogram) { + // Expect parent and child background colors, with parent color > child + // color. + EXPECT_GT(histogram[kParentBackgroundColor], 0u); + EXPECT_GT(histogram[kChildBackgroundColor], 0u); + EXPECT_GT(histogram[kParentBackgroundColor], + histogram[kChildBackgroundColor]); + })); +} TEST_F(FlutterEmbedderTest, HittestEmbedding) { LaunchParentViewInRealm(); @@ -513,77 +512,76 @@ TEST_F(FlutterEmbedderTest, HittestEmbedding) { })); } -// TEST_F(FlutterEmbedderTest, HittestDisabledEmbedding) { -// LaunchParentViewInRealm({"--no-hitTestable"}); - -// // Take screenshots until we see the child-view's embedded color. -// ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); - -// // Simulate a tap at the center of the child view. -// TryInject(/* x = */ 0, /* y = */ 0); - -// // The parent-view should change color. -// ASSERT_TRUE(TakeScreenshotUntil( -// kParentTappedColor, -// [](std::map histogram) { -// // Expect parent and child background colors, with parent color > -// child -// // color. -// EXPECT_EQ(histogram[kParentBackgroundColor], 0u); -// EXPECT_GT(histogram[kParentTappedColor], 0u); -// EXPECT_GT(histogram[kChildBackgroundColor], 0u); -// EXPECT_EQ(histogram[kChildTappedColor], 0u); -// EXPECT_GT(histogram[kParentTappedColor], -// histogram[kChildBackgroundColor]); -// })); -// } - -// TEST_F(FlutterEmbedderTest, EmbeddingWithOverlay) { -// LaunchParentViewInRealm({"--showOverlay"}); - -// // Take screenshot until we see the child-view's embedded color. -// ASSERT_TRUE(TakeScreenshotUntil( -// kChildBackgroundColor, -// [](std::map histogram) { -// // Expect parent, overlay and child background colors. -// // With parent color > child color and overlay color > child color. -// const size_t overlay_pixel_count = OverlayPixelCount(histogram); -// EXPECT_GT(histogram[kParentBackgroundColor], 0u); -// EXPECT_GT(overlay_pixel_count, 0u); -// EXPECT_GT(histogram[kChildBackgroundColor], 0u); -// EXPECT_GT(histogram[kParentBackgroundColor], -// histogram[kChildBackgroundColor]); -// EXPECT_GT(overlay_pixel_count, histogram[kChildBackgroundColor]); -// })); -// } - -// TEST_F(FlutterEmbedderTest, HittestEmbeddingWithOverlay) { -// LaunchParentViewInRealm({"--showOverlay"}); - -// // Take screenshot until we see the child-view's embedded color. -// ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); - -// // The bottom-left corner of the overlay is at the center of the screen, -// // which is at (0, 0) in the injection coordinate space. Inject a pointer -// // event just outside the overlay's bounds, and ensure that it goes to the -// // embedded view. -// TryInject(/* x = */ -1, /* y = */ 1); - -// // Take screenshot until we see the child-view's tapped color. -// ASSERT_TRUE(TakeScreenshotUntil( -// kChildTappedColor, -// [](std::map histogram) { -// // Expect parent, overlay and child background colors. -// // With parent color > child color and overlay color > child color. -// const size_t overlay_pixel_count = OverlayPixelCount(histogram); -// EXPECT_GT(histogram[kParentBackgroundColor], 0u); -// EXPECT_GT(overlay_pixel_count, 0u); -// EXPECT_EQ(histogram[kChildBackgroundColor], 0u); -// EXPECT_GT(histogram[kChildTappedColor], 0u); -// EXPECT_GT(histogram[kParentBackgroundColor], -// histogram[kChildTappedColor]); -// EXPECT_GT(overlay_pixel_count, histogram[kChildTappedColor]); -// })); -// } +TEST_F(FlutterEmbedderTest, HittestDisabledEmbedding) { + LaunchParentViewInRealm({"--no-hitTestable"}); + + // Take screenshots until we see the child-view's embedded color. + ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); + + // Simulate a tap at the center of the child view. + TryInject(/* x = */ 0, /* y = */ 0); + + // The parent-view should change color. + ASSERT_TRUE(TakeScreenshotUntil( + kParentTappedColor, + [](std::map histogram) { + // Expect parent and child background colors, with parent color > child + // color. + EXPECT_EQ(histogram[kParentBackgroundColor], 0u); + EXPECT_GT(histogram[kParentTappedColor], 0u); + EXPECT_GT(histogram[kChildBackgroundColor], 0u); + EXPECT_EQ(histogram[kChildTappedColor], 0u); + EXPECT_GT(histogram[kParentTappedColor], + histogram[kChildBackgroundColor]); + })); +} + +TEST_F(FlutterEmbedderTest, EmbeddingWithOverlay) { + LaunchParentViewInRealm({"--showOverlay"}); + + // Take screenshot until we see the child-view's embedded color. + ASSERT_TRUE(TakeScreenshotUntil( + kChildBackgroundColor, + [](std::map histogram) { + // Expect parent, overlay and child background colors. + // With parent color > child color and overlay color > child color. + const size_t overlay_pixel_count = OverlayPixelCount(histogram); + EXPECT_GT(histogram[kParentBackgroundColor], 0u); + EXPECT_GT(overlay_pixel_count, 0u); + EXPECT_GT(histogram[kChildBackgroundColor], 0u); + EXPECT_GT(histogram[kParentBackgroundColor], + histogram[kChildBackgroundColor]); + EXPECT_GT(overlay_pixel_count, histogram[kChildBackgroundColor]); + })); +} + +TEST_F(FlutterEmbedderTest, HittestEmbeddingWithOverlay) { + LaunchParentViewInRealm({"--showOverlay"}); + + // Take screenshot until we see the child-view's embedded color. + ASSERT_TRUE(TakeScreenshotUntil(kChildBackgroundColor)); + + // The bottom-left corner of the overlay is at the center of the screen, + // which is at (0, 0) in the injection coordinate space. Inject a pointer + // event just outside the overlay's bounds, and ensure that it goes to the + // embedded view. + TryInject(/* x = */ -1, /* y = */ 1); + + // Take screenshot until we see the child-view's tapped color. + ASSERT_TRUE(TakeScreenshotUntil( + kChildTappedColor, + [](std::map histogram) { + // Expect parent, overlay and child background colors. + // With parent color > child color and overlay color > child color. + const size_t overlay_pixel_count = OverlayPixelCount(histogram); + EXPECT_GT(histogram[kParentBackgroundColor], 0u); + EXPECT_GT(overlay_pixel_count, 0u); + EXPECT_EQ(histogram[kChildBackgroundColor], 0u); + EXPECT_GT(histogram[kChildTappedColor], 0u); + EXPECT_GT(histogram[kParentBackgroundColor], + histogram[kChildTappedColor]); + EXPECT_GT(overlay_pixel_count, histogram[kChildTappedColor]); + })); +} } // namespace flutter_embedder_test diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn index 5fe18345e16b8..ceaf8299f4a1b 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/BUILD.gn @@ -18,7 +18,6 @@ dart_library("lib") { "//flutter/tools/fuchsia/dart:zircon", "//flutter/tools/fuchsia/fidl:fuchsia.sys", "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", - "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart index 9d41e52476f3f..5fd521661150d 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/lib/parent_view.dart @@ -10,7 +10,6 @@ import 'dart:ui'; import 'package:args/args.dart'; import 'package:fidl_fuchsia_ui_app/fidl_async.dart'; import 'package:fidl_fuchsia_ui_views/fidl_async.dart'; -import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; import 'package:fuchsia_services/services.dart'; import 'package:vector_math/vector_math_64.dart' as vector_math_64; import 'package:zircon/zircon.dart'; @@ -60,7 +59,6 @@ class TestApp { final bool showOverlay; final bool hitTestable; final bool focusable; - final _responseListener = test_touch.TouchInputListenerProxy(); Color _backgroundColor = _blue; @@ -75,7 +73,12 @@ class TestApp { childView.create(hitTestable, focusable, (ByteData reply) { // Set up window allbacks. window.onPointerDataPacket = (PointerDataPacket packet) { - this.pointerDataPacket(packet); + for (final data in packet.data) { + if (data.change == PointerChange.down) { + this._backgroundColor = _black; + } + } + window.scheduleFrame(); }; window.onMetricsChanged = () { window.scheduleFrame(); @@ -156,38 +159,6 @@ class TestApp { window.render(sceneBuilder.build()); } - - void pointerDataPacket(PointerDataPacket packet) async { - int nowNanos = System.clockGetMonotonic(); - - for (PointerData data in packet.data) { - print('parent-view received tap: ${data.toStringFull()}'); - - if (data.change == PointerChange.down) { - this._backgroundColor = _black; - } - - if (data.change == PointerChange.down || data.change == PointerChange.move) { - Incoming.fromSvcPath() - ..connectToService(_responseListener) - ..close(); - - _respond(test_touch.TouchInputListenerReportTouchInputRequest( - localX: data.physicalX, - localY: data.physicalY, - timeReceived: nowNanos, - componentName: 'parent-view', - )); - } - } - - window.scheduleFrame(); - } - - void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async { - print('parent-view reporting touch input to TouchInputListener'); - await _responseListener.reportTouchInput(request); - } } class ChildView { diff --git a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml index 7cb17b79dd2fd..3eda9427a29c9 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml +++ b/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view/meta/parent-view.cml @@ -19,8 +19,6 @@ { protocol: [ "fuchsia.ui.app.ViewProvider", - "fuchsia.ui.test.input.TouchInputListener", - "fuchsia.ui.scenic.Scenic", ], }, { From 4e9450327203c01b9e60c253283075549ab62745 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 20:31:44 +0000 Subject: [PATCH 5/9] Minor refactor --- .../flutter/tests/integration/touch-input/BUILD.gn | 2 -- .../touch-input/embedding-flutter-view/BUILD.gn | 2 -- .../lib/embedding-flutter-view.dart | 1 - .../touch-input/embedding-flutter-view/pubspec.yaml | 8 ++++++++ .../tests/integration/touch-input/touch-input-test.cc | 4 ++-- testing/fuchsia/test_suites.yaml | 1 + 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn index f09b06f947885..766f87a2bad98 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn @@ -50,8 +50,6 @@ executable("touch-input-test-bin") { "touch-input-view:package", "//build/fuchsia/fidl:fuchsia.ui.gfx", "//flutter/fml", - "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/child-view:package", - "//flutter/shell/platform/fuchsia/flutter/tests/integration/embedder/parent-view:package", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:color", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:portable_ui_test", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:screenshot", diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn index e291e50fb1dba..665050687076d 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/BUILD.gn @@ -13,13 +13,11 @@ dart_library("lib") { sources = [ "embedding-flutter-view.dart" ] deps = [ - "//flutter/shell/platform/fuchsia/dart:vector_math", "//flutter/tools/fuchsia/dart:fuchsia_services", "//flutter/tools/fuchsia/dart:zircon", "//flutter/tools/fuchsia/fidl:fuchsia.ui.app", "//flutter/tools/fuchsia/fidl:fuchsia.ui.scenic", "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", - "//flutter/tools/fuchsia/fidl:fuchsia.ui.test.input", "//flutter/tools/fuchsia/fidl:fuchsia.ui.views", ] } diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart index eede613963e62..745556bccc20b 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/lib/embedding-flutter-view.dart @@ -11,7 +11,6 @@ import 'package:fidl_fuchsia_ui_app/fidl_async.dart'; import 'package:fidl_fuchsia_ui_views/fidl_async.dart'; import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_touch; import 'package:fuchsia_services/services.dart'; -import 'package:vector_math/vector_math_64.dart' as vector_math_64; import 'package:zircon/zircon.dart'; void main(List args) { diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml index e69de29bb2d1d..cc78c78f090eb 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml @@ -0,0 +1,8 @@ +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +name: touch-input-view + +environment: + sdk: '>=2.18.0 <3.0.0' diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc index 97ac68ffbe809..47a45a547bb97 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc @@ -131,6 +131,8 @@ using RealmBuilder = component_testing::RealmBuilder; constexpr zx::duration kTimeout = zx::min(1); // Timeout for Scenic's |TakeScreenshot| FIDL call. constexpr zx::duration kScreenshotTimeout = zx::sec(10); +constexpr fuchsia_test_utils::Color kChildBackgroundColor = {0xFF, 0x00, 0xFF, + 0xFF}; // Pink constexpr auto kTestUIStackUrl = "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/" @@ -318,8 +320,6 @@ class FlutterEmbedTapTest : public FlutterTapTestBase { bool WaitForEmbed() { return RunLoopWithTimeoutOrUntil( [this] { - constexpr fuchsia_test_utils::Color kChildBackgroundColor = { - 0xFF, 0x00, 0xFF, 0xFF}; // Pink fuchsia::ui::scenic::ScreenshotData screenshot_out; scenic_->TakeScreenshot( [this, &screenshot_out]( diff --git a/testing/fuchsia/test_suites.yaml b/testing/fuchsia/test_suites.yaml index 25e91cedefb93..abc05afc36d05 100644 --- a/testing/fuchsia/test_suites.yaml +++ b/testing/fuchsia/test_suites.yaml @@ -53,3 +53,4 @@ - touch-input-test-0.far - oot_flutter_jit_runner-0.far - gen/flutter/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-view/touch-input-view/touch-input-view.far + - gen/flutter/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/embedding-flutter-view/embedding-flutter-view.far From b8956ff7883fa439c94554b46c2f0d37451105ab Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 22:15:05 +0000 Subject: [PATCH 6/9] Remove unused dependencies --- .../tests/integration/touch-input/BUILD.gn | 2 - .../touch-input/touch-input-test.cc | 53 ++++------ .../integration/utils/portable_ui_test.cc | 96 ++++++++++++------- .../integration/utils/portable_ui_test.h | 8 +- 4 files changed, 83 insertions(+), 76 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn index 766f87a2bad98..051fc40bbf33b 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/BUILD.gn @@ -50,9 +50,7 @@ executable("touch-input-test-bin") { "touch-input-view:package", "//build/fuchsia/fidl:fuchsia.ui.gfx", "//flutter/fml", - "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:color", "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:portable_ui_test", - "//flutter/shell/platform/fuchsia/flutter/tests/integration/utils:screenshot", "//third_party/googletest:gtest", "//third_party/googletest:gtest_main", ] diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc index 47a45a547bb97..9ebf909be4437 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/touch-input-test.cc @@ -46,9 +46,7 @@ #include #include "flutter/fml/logging.h" -#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/color.h" #include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h" -#include "flutter/shell/platform/fuchsia/flutter/tests/integration/utils/screenshot.h" // This test exercises the touch input dispatch path from Input Pipeline to a // Scenic client. It is a multi-component test, and carefully avoids sleeping or @@ -129,10 +127,6 @@ using RealmBuilder = component_testing::RealmBuilder; // Max timeout in failure cases. // Set this as low as you can that still works across all test platforms. constexpr zx::duration kTimeout = zx::min(1); -// Timeout for Scenic's |TakeScreenshot| FIDL call. -constexpr zx::duration kScreenshotTimeout = zx::sec(10); -constexpr fuchsia_test_utils::Color kChildBackgroundColor = {0xFF, 0x00, 0xFF, - 0xFF}; // Pink constexpr auto kTestUIStackUrl = "fuchsia-pkg://fuchsia.com/gfx-root-presenter-test-ui-stack#meta/" @@ -231,6 +225,22 @@ class FlutterTapTestBase : public PortableUITest, << "\n\n>> Test did not complete in time, terminating. <<\n\n"; }, kTimeout); + + // Get the display dimensions. + FML_LOG(INFO) << "Waiting for scenic display info"; + scenic_ = realm_root()->template Connect(); + scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { + display_width_ = display_info.width_in_px; + display_height_ = display_info.height_in_px; + FML_LOG(INFO) << "Got display_width = " << display_width_ + << " and display_height = " << display_height_; + }); + RunLoopUntil( + [this] { return display_width_ != 0 && display_height_ != 0; }); + + // Register input injection device. + FML_LOG(INFO) << "Registering input injection device"; + RegisterTouchScreen(); } bool LastEventReceivedMatches(float expected_x, @@ -314,32 +324,6 @@ class FlutterTapTest : public FlutterTapTestBase { }; class FlutterEmbedTapTest : public FlutterTapTestBase { - protected: - // Takes a screenshot and waits for child view to embed itself to the parent - // view - bool WaitForEmbed() { - return RunLoopWithTimeoutOrUntil( - [this] { - fuchsia::ui::scenic::ScreenshotData screenshot_out; - scenic_->TakeScreenshot( - [this, &screenshot_out]( - fuchsia::ui::scenic::ScreenshotData screenshot, bool status) { - EXPECT_TRUE(status) << "Failed to take screenshot"; - screenshot_out = std::move(screenshot); - QuitLoop(); - }); - EXPECT_FALSE(RunLoopWithTimeout(kScreenshotTimeout)) - << "Timed out waiting for screenshot."; - - auto screenshot = fuchsia_test_utils::Screenshot(screenshot_out); - auto histogram = screenshot.Histogram(); - - bool color_found = histogram[kChildBackgroundColor] > 0; - return color_found; - }, - kTimeout); - } - private: void ExtendRealm() override { FML_LOG(INFO) << "Extending realm"; @@ -417,11 +401,8 @@ INSTANTIATE_TEST_SUITE_P(FlutterEmbedTapTestParameterized, TEST_P(FlutterEmbedTapTest, FlutterEmbedTap) { // Launch view FML_LOG(INFO) << "Initializing scene"; - LaunchClient(); + LaunchClientWithEmbeddedView(); FML_LOG(INFO) << "Client launched"; - // Wait for child view to embed and render to proceed with the test. - WaitForEmbed(); - FML_LOG(INFO) << "Embedded child view has rendered"; { // Embedded child view takes up the left side of the screen diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc index 33ab95404e2fa..6327678698eb3 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc @@ -32,6 +32,7 @@ using fuchsia_test_utils::CheckViewExistsInSnapshot; void PortableUITest::SetUp() { SetUpRealmBase(); ExtendRealm(); + realm_ = std::make_unique(realm_builder_.Build()); } void PortableUITest::SetUpRealmBase() { @@ -136,27 +137,15 @@ void PortableUITest::WatchViewGeometry() { }); } -bool PortableUITest::HasViewConnected( - fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, - std::optional& - watch_response, - zx_koid_t view_ref_koid) { - std::optional watch_result; - view_tree_watcher->Watch( - [&watch_result](auto response) { watch_result = std::move(response); }); - FML_LOG(INFO) << "Waiting for view tree watch result"; - RunLoopUntil([&watch_result] { return watch_result.has_value(); }); - FML_LOG(INFO) << "Received for view tree watch result"; - if (CheckViewExistsInUpdates(watch_result->updates(), view_ref_koid)) { - watch_response = std::move(watch_result); - }; - return watch_response.has_value(); +bool PortableUITest::HasViewConnected(zx_koid_t view_ref_koid) { + return last_view_tree_snapshot_.has_value() && + CheckViewExistsInSnapshot(*last_view_tree_snapshot_, view_ref_koid); } void PortableUITest::LaunchClient() { - realm_ = std::make_unique(realm_builder_.Build()); + // realm_ = std::make_unique(realm_builder_.Build()); - RegisterTouchScreen(); + // RegisterTouchScreen(); scene_provider_ = realm_->Connect(); scene_provider_.set_error_handler( @@ -174,28 +163,69 @@ void PortableUITest::LaunchClient() { FML_LOG(INFO) << "Waiting for client view ref koid"; RunLoopUntil([this] { return client_root_view_ref_koid_.has_value(); }); + WatchViewGeometry(); + FML_LOG(INFO) << "Waiting for client view to connect"; // Wait for the client view to get attached to the view tree. - std::optional - watch_response; - RunLoopUntil([this, &watch_response] { - return HasViewConnected(view_tree_watcher_, watch_response, - *client_root_view_ref_koid_); - }); + RunLoopUntil( + [this] { return HasViewConnected(*client_root_view_ref_koid_); }); FML_LOG(INFO) << "Client view has rendered"; - scenic_ = realm_->Connect(); - FML_LOG(INFO) << "Launched parent view"; + // scenic_ = realm_->Connect(); + // FML_LOG(INFO) << "Launched parent view"; + + // // Get the display dimensions. + // FML_LOG(INFO) << "Waiting for scenic display info"; + // scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { + // display_width_ = display_info.width_in_px; + // display_height_ = display_info.height_in_px; + // FML_LOG(INFO) << "Got display_width = " << display_width_ + // << " and display_height = " << display_height_; + // }); + // RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; }); +} + +void PortableUITest::LaunchClientWithEmbeddedView() { + LaunchClient(); + // At this point, the parent view must have rendered, so we just need to wait + // for the embedded view. + RunLoopUntil([this] { + if (!last_view_tree_snapshot_.has_value() || + !last_view_tree_snapshot_->has_views()) { + return false; + } + + if (!client_root_view_ref_koid_.has_value()) { + return false; + } - // Get the display dimensions. - FML_LOG(INFO) << "Waiting for scenic display info"; - scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { - display_width_ = display_info.width_in_px; - display_height_ = display_info.height_in_px; - FML_LOG(INFO) << "Got display_width = " << display_width_ - << " and display_height = " << display_height_; + for (const auto& view : last_view_tree_snapshot_->views()) { + if (!view.has_view_ref_koid() || + view.view_ref_koid() != *client_root_view_ref_koid_) { + continue; + } + + if (view.children().empty()) { + return false; + } + + // NOTE: We can't rely on the presence of the child view in + // `view.children()` to guarantee that it has rendered. The child view + // also needs to be present in `last_view_tree_snapshot_->views`. + return std::count_if( + last_view_tree_snapshot_->views().begin(), + last_view_tree_snapshot_->views().end(), + [view_to_find = + view.children().back()](const auto& view_to_check) { + return view_to_check.has_view_ref_koid() && + view_to_check.view_ref_koid() == view_to_find; + }) > 0; + } + + return false; }); - RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; }); + + FML_LOG(INFO) << "Embedded view has rendered"; } void PortableUITest::RegisterTouchScreen() { diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h index 174cc01793a08..645085f70b393 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h @@ -48,14 +48,12 @@ class PortableUITest : public ::loop_fixture::RealLoop { // Attaches a client view to the scene, and waits for it to render. void LaunchClient(); + // Attaches a view with an embedded child view to the scene, and waits for it to render. + void LaunchClientWithEmbeddedView(); // Returns true when the specified view is fully connected to the scene AND // has presented at least one frame of content. - bool HasViewConnected( - fuchsia::ui::observation::geometry::ViewTreeWatcherPtr& view_tree_watcher, - std::optional& - watch_response, - zx_koid_t view_ref_koid); + bool HasViewConnected(zx_koid_t view_ref_koid); // Registers a fake touch screen device with an injection coordinate space // spanning [-1000, 1000] on both axes. From 5e6a55a7b9503409e6ceca20a7c6afdd3f77471b Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 22:15:27 +0000 Subject: [PATCH 7/9] Lint CC files --- .../flutter/tests/integration/utils/portable_ui_test.cc | 6 ++++-- .../flutter/tests/integration/utils/portable_ui_test.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc index 6327678698eb3..f4fa130caa700 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc @@ -176,13 +176,15 @@ void PortableUITest::LaunchClient() { // // Get the display dimensions. // FML_LOG(INFO) << "Waiting for scenic display info"; - // scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) { + // scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) + // { // display_width_ = display_info.width_in_px; // display_height_ = display_info.height_in_px; // FML_LOG(INFO) << "Got display_width = " << display_width_ // << " and display_height = " << display_height_; // }); - // RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; }); + // RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; + // }); } void PortableUITest::LaunchClientWithEmbeddedView() { diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h index 645085f70b393..6b3978e19ce66 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.h @@ -48,7 +48,8 @@ class PortableUITest : public ::loop_fixture::RealLoop { // Attaches a client view to the scene, and waits for it to render. void LaunchClient(); - // Attaches a view with an embedded child view to the scene, and waits for it to render. + // Attaches a view with an embedded child view to the scene, and waits for it + // to render. void LaunchClientWithEmbeddedView(); // Returns true when the specified view is fully connected to the scene AND From 816efc6a67eda05c794a884c219a010e6d4bd582 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 26 Oct 2022 22:17:21 +0000 Subject: [PATCH 8/9] Remove comments --- .../integration/utils/portable_ui_test.cc | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc index f4fa130caa700..b4a60fd882492 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc +++ b/shell/platform/fuchsia/flutter/tests/integration/utils/portable_ui_test.cc @@ -143,10 +143,6 @@ bool PortableUITest::HasViewConnected(zx_koid_t view_ref_koid) { } void PortableUITest::LaunchClient() { - // realm_ = std::make_unique(realm_builder_.Build()); - - // RegisterTouchScreen(); - scene_provider_ = realm_->Connect(); scene_provider_.set_error_handler( [](auto) { FML_LOG(ERROR) << "Error from test scene provider"; }); @@ -170,21 +166,6 @@ void PortableUITest::LaunchClient() { RunLoopUntil( [this] { return HasViewConnected(*client_root_view_ref_koid_); }); FML_LOG(INFO) << "Client view has rendered"; - - // scenic_ = realm_->Connect(); - // FML_LOG(INFO) << "Launched parent view"; - - // // Get the display dimensions. - // FML_LOG(INFO) << "Waiting for scenic display info"; - // scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo display_info) - // { - // display_width_ = display_info.width_in_px; - // display_height_ = display_info.height_in_px; - // FML_LOG(INFO) << "Got display_width = " << display_width_ - // << " and display_height = " << display_height_; - // }); - // RunLoopUntil([this] { return display_width_ != 0 && display_height_ != 0; - // }); } void PortableUITest::LaunchClientWithEmbeddedView() { From de075cfc6586ad7bb4b8ece33cf7f8a14b8fef4d Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 7 Nov 2022 20:35:29 +0000 Subject: [PATCH 9/9] Rename pubspec --- .../integration/touch-input/embedding-flutter-view/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml index cc78c78f090eb..fcd78ccdc8d9a 100644 --- a/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml +++ b/shell/platform/fuchsia/flutter/tests/integration/touch-input/embedding-flutter-view/pubspec.yaml @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -name: touch-input-view +name: embedding-flutter-view environment: sdk: '>=2.18.0 <3.0.0'