Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Minor refactor
  • Loading branch information
lin-erik committed Oct 19, 2022
commit b41ce825ab4a1876f45a4211b9aa357455e9157f
Original file line number Diff line number Diff line change
Expand Up @@ -123,46 +123,34 @@ using component_testing::Route;
using fuchsia_test_utils::PortableUITest;

using RealmBuilder = component_testing::RealmBuilder;
// Alias for Component child name as provided to Realm Builder.
using ChildName = std::string;
// Alias for Component Legacy URL as provided to Realm Builder.
using LegacyUrl = std::string;

// 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 auto kMockResponseListener = "response_listener";

enum class TapLocation { kTopLeft, kTopRight };

// Combines all vectors in `vecs` into one.
template <typename T>
std::vector<T> merge(std::initializer_list<std::vector<T>> vecs) {
std::vector<T> result;
for (auto v : vecs) {
result.insert(result.end(), v.begin(), v.end());
}
return result;
}
constexpr auto kMockTouchInputListener = "touch_input_listener";
constexpr auto kFlutterRealm = "two-flutter";
constexpr auto kFlutterRealmUrl =
"fuchsia-pkg://fuchsia.com/two-flutter#meta/two-flutter.cm";

bool CompareDouble(double f0, double f1, double epsilon) {
return std::abs(f0 - f1) <= epsilon;
}

// // This component implements the test.touch.ResponseListener protocol
// // and the interface for a RealmBuilder LocalComponent. A LocalComponent
// // is a component that is implemented here in the test, as opposed to
// elsewhere
// // in the system. When it's inserted to the realm, it will act like a proper
// // component. This is accomplished, in part, because the realm_builder
// // library creates the necessary plumbing. It creates a manifest for the
// // component and routes all capabilities to and from it.
class ResponseListenerServer
// This component implements the TouchInput protocol
// and the interface for a RealmBuilder LocalComponent. A LocalComponent
// is a component that is implemented here in the test, as opposed to
// elsewhere in the system. When it's inserted to the realm, it will act
// like a proper component. This is accomplished, in part, because the
// realm_builder library creates the necessary plumbing. It creates a manifest
// for the component and routes all capabilities to and from it.
// LocalComponent:
// https://fuchsia.dev/fuchsia-src/development/testing/components/realm_builder#mock-components
class TouchInputListenerServer
: public fuchsia::ui::test::input::TouchInputListener,
public LocalComponent {
public:
explicit ResponseListenerServer(async_dispatcher_t* dispatcher)
explicit TouchInputListenerServer(async_dispatcher_t* dispatcher)
: dispatcher_(dispatcher) {}

// |fuchsia::ui::test::input::TouchInputListener|
Expand All @@ -177,18 +165,16 @@ class ResponseListenerServer
// When the component framework requests for this component to start, this
// method will be invoked by the realm_builder library.
void Start(std::unique_ptr<LocalComponentHandles> local_handles) override {
FML_LOG(INFO) << "Starting ResponseListenerServer";
FML_LOG(INFO) << "Starting TouchInputListenerServer";
// When this component starts, add a binding to the
// test.touch.ResponseListener protocol to this component's outgoing
// directory.
// protocol to this component's outgoing directory.
ASSERT_EQ(ZX_OK, local_handles->outgoing()->AddPublicService(
fidl::InterfaceRequestHandler<
fuchsia::ui::test::input::TouchInputListener>(
[this](auto request) {
bindings_.AddBinding(this, std::move(request),
dispatcher_);
})));
FML_LOG(INFO) << "Handle added for ResponseListenerServer";
local_handles_.emplace_back(std::move(local_handles));
}

Expand Down Expand Up @@ -245,45 +231,10 @@ class FlutterTapTest : public PortableUITest,
RegisterTouchScreen();
}

// Routes needed to setup Flutter client.
static std::vector<Route> GetFlutterRoutes(ChildRef target) {
return {
{.capabilities = {Protocol{
fuchsia::ui::test::input::TouchInputListener::Name_}},
.source = ChildRef{kMockResponseListener},
.targets = {target}},
// {.capabilities = {Protocol{fuchsia::logger::LogSink::Name_},
// Protocol{fuchsia::sysmem::Allocator::Name_},
// Protocol{
// fuchsia::tracing::provider::Registry::Name_}},
// .source = ParentRef(),
// .targets = {target}},
// {.capabilities = {Protocol{fuchsia::ui::scenic::Scenic::Name_}},
// .source = kTestUIStackRef,
// .targets = {target}},
};
}

std::vector<Route> GetTestRoutes() {
return merge(
{GetFlutterRoutes(ChildRef{kFlutterRealm}),
{
{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
.source = ChildRef{kFlutterRealm},
.targets = {ParentRef()}},
}});
}

std::vector<std::pair<ChildName, LegacyUrl>> GetTestV2Components() {
return {
std::make_pair(kFlutterRealm, kFlutterRealmUrl),
};
};

bool LastEventReceivedMatches(float expected_x,
float expected_y,
std::string component_name) {
const auto& events_received = response_listener_server_->events_received();
const auto& events_received = touch_input_listener_server_->events_received();

if (events_received.empty()) {
return false;
Expand Down Expand Up @@ -313,51 +264,46 @@ class FlutterTapTest : public PortableUITest,
uint32_t display_width() const { return display_width_; }
uint32_t display_height() const { return display_height_; }

static constexpr auto kFlutterRealm = "two-flutter";
static constexpr auto kFlutterRealmUrl =
"fuchsia-pkg://fuchsia.com/two-flutter#meta/two-flutter.cm";

private:
void ExtendRealm() override {
// Key part of service setup: have this test component vend the
// |ResponseListener| service in the constructed realm.
response_listener_server_ =
std::make_unique<ResponseListenerServer>(dispatcher());
realm_builder()->AddLocalChild(kMockResponseListener,
response_listener_server_.get());

// Add components specific for this test case to the realm.
// for (const auto& [name, component] : GetTestV2Components()) {
// |TouchInputListener| service in the constructed realm.
touch_input_listener_server_ =
std::make_unique<TouchInputListenerServer>(dispatcher());
realm_builder()->AddLocalChild(kMockTouchInputListener,
touch_input_listener_server_.get());

realm_builder()->AddChild(kFlutterRealm, kFlutterRealmUrl,
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 = ChildRef{kMockResponseListener},
.source = ChildRef{kMockTouchInputListener},
.targets = {kFlutterJitRunnerRef, ChildRef{kFlutterRealm}}});

// Add the necessary routing for each of the extra components added
// above.
// for (const auto& route : GetTestRoutes()) {
realm_builder()->AddRoute(
Route{.capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
.source = ChildRef{kFlutterRealm},
.targets = {ParentRef()}});
// }
}

ParamType GetTestUIStackUrl() override { return GetParam(); };

std::unique_ptr<ResponseListenerServer> response_listener_server_;
std::unique_ptr<TouchInputListenerServer> touch_input_listener_server_;

fuchsia::ui::scenic::ScenicPtr scenic_;
uint32_t display_width_ = 0;
uint32_t display_height_ = 0;
};

// 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,
Expand All @@ -371,7 +317,12 @@ TEST_P(FlutterTapTest, FlutterTap) {
LaunchClient();
FML_LOG(INFO) << "Client launched";

// two-flutter logical coordinate space doesn't match the fake touch screen injector's coordinate space,
// which spans [-1000, 1000] on both axes. Scenic handles figuring out where in the coordinate space
// to inject a touch event (this is fixed to a display's bounds).
InjectTap(-500, -500);
// For a (-500 [x], -500 [y]) tap, we expect a touch event in the middle of the upper-left quadrant
// of the screen.
RunLoopUntil([this] {
return LastEventReceivedMatches(
/*expected_x=*/static_cast<float>(display_width() / 4.0f),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ class MyApp {
void beginFrame(Duration duration) {
// Convert physical screen size of device to values
final pixelRatio = window.devicePixelRatio;
print('beginFrame pixelRatio: $pixelRatio');
final size = window.physicalSize / pixelRatio;
print('beginFrame size: $size');
final physicalBounds = Offset.zero & size * pixelRatio;
print('beginFrame physicalBounds: $physicalBounds');
// Set up Canvas that uses the screen size
final recorder = PictureRecorder();
final canvas = Canvas(recorder, physicalBounds);
Expand Down Expand Up @@ -108,11 +111,6 @@ class MyApp {

void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async {
print('reporting touch input to responseListener');
try {
await _responseListener.reportTouchInput(request);
} catch(e) {
print('received error while attempting to report touch input');
print(e);
}
await _responseListener.reportTouchInput(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ source_set("portable_ui_test") {
"$fuchsia_sdk_root/fidl:fuchsia.ui.scenic",
"$fuchsia_sdk_root/fidl:fuchsia.ui.test.input",
"$fuchsia_sdk_root/fidl:fuchsia.ui.test.scene",
"$fuchsia_sdk_root/fidl:fuchsia.ui.test.scene",
"$fuchsia_sdk_root/pkg:async-loop-testing",
"$fuchsia_sdk_root/pkg:sys_component_cpp_testing",
"//flutter/fml",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ void PortableUITest::SetUpRealmBase() {
Protocol{fuchsia::sys::Environment::Name_},
Protocol{fuchsia::sysmem::Allocator::Name_},
Protocol{fuchsia::tracing::provider::Registry::Name_},
Protocol{"fuchsia.posix.socket.Provider"},
Protocol{"fuchsia.ui.input.ImeService"},
Protocol{"fuchsia.ui.pointerinjector.Registry"},
Protocol{fuchsia::ui::input::ImeService::Name_},
Protocol{kPointerInjectorRegistryName},
Protocol{kPosixSocketProviderName},
Protocol{kVulkanLoaderServiceName},
component_testing::Directory{"config-data"},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ class PortableUITest : public ::loop_fixture::RealLoop {
// we must encode the names manually here.
static constexpr auto kVulkanLoaderServiceName =
"fuchsia.vulkan.loader.Loader";
static constexpr auto kProfileProviderServiceName =
"fuchsia.sheduler.ProfileProvider";
static constexpr auto kPosixSocketProviderName =
"fuchsia.posix.socket.Provider";
static constexpr auto kPointerInjectorRegistryName =
"fuchsia.ui.pointerinjector.Registry";

// The naming and references used by Realm Builder
static constexpr auto kTestUIStack = "ui";
static constexpr auto kTestUIStackRef =
component_testing::ChildRef{kTestUIStack};
Expand Down Expand Up @@ -70,7 +74,8 @@ class PortableUITest : public ::loop_fixture::RealLoop {
// Configures the test-specific component topology.
virtual void ExtendRealm() = 0;

// Returns the test-ui-stack component url to use in this test.
// Returns the test-specific test-ui-stack component url to use.
// Usually overriden to return a value from gtest GetParam()
virtual std::string GetTestUIStackUrl() = 0;

// Helper method to watch watch for view geometry updates.
Expand Down