mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[fuchsia] Stop calling FIDL from Dart in Flutter integration tests (flutter/engine#41669)
As we move the Dart FIDL bindings we need to stop calling FIDL methods from Dart in the Flutter repo. This only affects some integration tests. This moves the FIDL calls into C++ and uses platform messages to make the functionality available to the Dart tests.
This commit is contained in:
parent
de642efdac
commit
4579687380
@ -2799,7 +2799,6 @@ ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_runner.h + ../.
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_test_component_controller.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_test_component_controller.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/script_runner_snapshot.dart + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/shim.dart + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/snapshot.cc.tmpl + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/snapshot.dart + ../../../flutter/LICENSE
|
||||
@ -5422,7 +5421,6 @@ FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_runner.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_test_component_controller.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/dart_test_component_controller.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/script_runner_snapshot.dart
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/shim.dart
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/snapshot.cc.tmpl
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/dart_runner/embedder/snapshot.dart
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// Core SDK libraries.
|
||||
import 'dart:async';
|
||||
import 'dart:core';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:math';
|
||||
import 'dart:fuchsia.builtin';
|
||||
import 'dart:zircon';
|
||||
import 'dart:fuchsia';
|
||||
import 'dart:typed_data';
|
||||
|
||||
// If new imports are added to this list, then it is also necessary to ensure
|
||||
// that the dart_deps parameter in the rule
|
||||
// gen_snapshot_cc("script_runner_snapshot") in the BUILD.gn file in this
|
||||
// directory is updated with any new dependencies.
|
||||
|
||||
import 'package:fuchsia/fuchsia.dart';
|
||||
import 'package:zircon/zircon.dart';
|
||||
|
||||
// FIDL bindings and application libraries.
|
||||
import 'package:lib.app.dart/app.dart';
|
||||
import 'package:fidl/fidl.dart';
|
||||
|
||||
// From //sdk/fidl/fuchsia.modular
|
||||
import 'package:fidl_fuchsia_modular/fidl_async.dart';
|
||||
@ -162,9 +162,10 @@ template("runner_sources") {
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.app",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.composition",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.pointer",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.views",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.scenic",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.pointerinjector",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.scenic",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.test.input",
|
||||
"$fuchsia_sdk_root/fidl:fuchsia.ui.views",
|
||||
"$fuchsia_sdk_root/pkg:async-cpp",
|
||||
"$fuchsia_sdk_root/pkg:async-default",
|
||||
"$fuchsia_sdk_root/pkg:async-loop",
|
||||
|
||||
@ -582,7 +582,7 @@ void Engine::Initialize(
|
||||
session_connection_->AwaitVsyncForSecondaryCallback(cb);
|
||||
}
|
||||
},
|
||||
product_config](flutter::Shell& shell) mutable {
|
||||
product_config, svc](flutter::Shell& shell) mutable {
|
||||
OnShaderWarmup on_shader_warmup = nullptr;
|
||||
if (product_config.enable_shader_warmup()) {
|
||||
FML_DCHECK(surface_producer_);
|
||||
@ -636,7 +636,8 @@ void Engine::Initialize(
|
||||
std::move(on_request_announce_callback),
|
||||
std::move(on_shader_warmup),
|
||||
std::move(await_vsync_callback),
|
||||
std::move(await_vsync_for_secondary_callback_callback));
|
||||
std::move(await_vsync_for_secondary_callback_callback),
|
||||
std::move(svc));
|
||||
} else {
|
||||
platform_view = std::make_unique<flutter_runner::GfxPlatformView>(
|
||||
shell, shell.GetTaskRunners(), std::move(view_ref),
|
||||
@ -655,7 +656,8 @@ void Engine::Initialize(
|
||||
std::move(on_semantics_node_update_callback),
|
||||
std::move(on_request_announce_callback),
|
||||
std::move(on_shader_warmup), std::move(await_vsync_callback),
|
||||
std::move(await_vsync_for_secondary_callback_callback));
|
||||
std::move(await_vsync_for_secondary_callback_callback),
|
||||
std::move(svc));
|
||||
}
|
||||
return platform_view;
|
||||
});
|
||||
|
||||
@ -32,7 +32,8 @@ FlatlandPlatformView::FlatlandPlatformView(
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback)
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc)
|
||||
: PlatformView(true /* is_flatland */,
|
||||
delegate,
|
||||
std::move(task_runners),
|
||||
@ -52,7 +53,8 @@ FlatlandPlatformView::FlatlandPlatformView(
|
||||
std::move(on_request_announce_callback),
|
||||
std::move(on_shader_warmup),
|
||||
std::move(await_vsync_callback),
|
||||
std::move(await_vsync_for_secondary_callback_callback)),
|
||||
std::move(await_vsync_for_secondary_callback_callback),
|
||||
std::move(dart_application_svc)),
|
||||
parent_viewport_watcher_(parent_viewport_watcher.Bind()),
|
||||
on_create_view_callback_(std::move(on_create_view_callback)),
|
||||
on_destroy_view_callback_(std::move(on_destroy_view_callback)),
|
||||
|
||||
@ -46,7 +46,8 @@ class FlatlandPlatformView final : public flutter_runner::PlatformView {
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback);
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc);
|
||||
~FlatlandPlatformView() override;
|
||||
|
||||
void OnGetLayout(fuchsia::ui::composition::LayoutInfo info);
|
||||
|
||||
@ -33,7 +33,8 @@ GfxPlatformView::GfxPlatformView(
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback)
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc)
|
||||
: PlatformView(false /* is_flatland */,
|
||||
delegate,
|
||||
std::move(task_runners),
|
||||
@ -53,7 +54,8 @@ GfxPlatformView::GfxPlatformView(
|
||||
std::move(on_request_announce_callback),
|
||||
std::move(on_shader_warmup),
|
||||
std::move(await_vsync_callback),
|
||||
std::move(await_vsync_for_secondary_callback_callback)),
|
||||
std::move(await_vsync_for_secondary_callback_callback),
|
||||
std::move(dart_application_svc)),
|
||||
session_listener_binding_(this, std::move(session_listener_request)),
|
||||
session_listener_error_callback_(
|
||||
std::move(on_session_listener_error_callback)),
|
||||
|
||||
@ -50,7 +50,8 @@ class GfxPlatformView final : public flutter_runner::PlatformView,
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback);
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc);
|
||||
|
||||
~GfxPlatformView() override;
|
||||
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flow/embedded_views.h"
|
||||
#include "pointer_injector_delegate.h"
|
||||
#define RAPIDJSON_HAS_STDSTRING 1
|
||||
|
||||
#include "platform_view.h"
|
||||
|
||||
#include <fuchsia/ui/app/cpp/fidl.h>
|
||||
#include <zircon/status.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
@ -24,16 +25,35 @@
|
||||
#include "third_party/rapidjson/include/rapidjson/writer.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "pointer_injector_delegate.h"
|
||||
#include "runtime/dart/utils/inlines.h"
|
||||
#include "text_delegate.h"
|
||||
#include "vsync_waiter.h"
|
||||
|
||||
namespace {
|
||||
// Helper to extract a given member with a given type from a rapidjson object.
|
||||
template <typename T, typename O, typename F>
|
||||
bool CallWithMember(O obj, const char* member_name, F func) {
|
||||
auto it = obj.FindMember(member_name);
|
||||
if (it == obj.MemberEnd()) {
|
||||
return false;
|
||||
}
|
||||
if (!it->value.template Is<T>()) {
|
||||
return false;
|
||||
}
|
||||
func(it->value.template Get<T>());
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
static constexpr char kFlutterPlatformChannel[] = "flutter/platform";
|
||||
static constexpr char kAccessibilityChannel[] = "flutter/accessibility";
|
||||
static constexpr char kFlutterPlatformViewsChannel[] = "flutter/platform_views";
|
||||
static constexpr char kFuchsiaShaderWarmupChannel[] = "fuchsia/shader_warmup";
|
||||
static constexpr char kFuchsiaInputTestChannel[] = "fuchsia/input_test";
|
||||
static constexpr char kFuchsiaChildViewChannel[] = "fuchsia/child_view";
|
||||
|
||||
PlatformView::PlatformView(
|
||||
bool is_flatland,
|
||||
@ -56,7 +76,8 @@ PlatformView::PlatformView(
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback)
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc)
|
||||
: flutter::PlatformView(delegate, std::move(task_runners)),
|
||||
external_view_embedder_(external_view_embedder),
|
||||
focus_delegate_(
|
||||
@ -75,6 +96,7 @@ PlatformView::PlatformView(
|
||||
await_vsync_callback_(await_vsync_callback),
|
||||
await_vsync_for_secondary_callback_callback_(
|
||||
await_vsync_for_secondary_callback_callback),
|
||||
dart_application_svc_(dart_application_svc),
|
||||
weak_factory_(this) {
|
||||
fuchsia::ui::views::ViewRef view_ref_clone;
|
||||
fidl::Clone(view_ref, &view_ref_clone);
|
||||
@ -140,6 +162,51 @@ PlatformView::PlatformView(
|
||||
std::move(pointerinjector_registry), std::move(view_ref_clone),
|
||||
is_flatland);
|
||||
|
||||
// This is only used by the integration tests.
|
||||
if (dart_application_svc) {
|
||||
// Connect to TouchInputListener
|
||||
fuchsia::ui::test::input::TouchInputListenerHandle touch_input_listener;
|
||||
zx_status_t touch_input_listener_status =
|
||||
dart_application_svc
|
||||
->Connect<fuchsia::ui::test::input::TouchInputListener>(
|
||||
touch_input_listener.NewRequest());
|
||||
if (touch_input_listener_status != ZX_OK) {
|
||||
FML_LOG(WARNING)
|
||||
<< "fuchsia::ui::test::input::TouchInputListener connection failed: "
|
||||
<< zx_status_get_string(touch_input_listener_status);
|
||||
} else {
|
||||
touch_input_listener_.Bind(std::move(touch_input_listener));
|
||||
}
|
||||
|
||||
// Connect to KeyboardInputListener
|
||||
fuchsia::ui::test::input::KeyboardInputListenerHandle
|
||||
keyboard_input_listener;
|
||||
zx_status_t keyboard_input_listener_status =
|
||||
dart_application_svc
|
||||
->Connect<fuchsia::ui::test::input::KeyboardInputListener>(
|
||||
keyboard_input_listener.NewRequest());
|
||||
if (keyboard_input_listener_status != ZX_OK) {
|
||||
FML_LOG(WARNING) << "fuchsia::ui::test::input::KeyboardInputListener "
|
||||
"connection failed: "
|
||||
<< zx_status_get_string(keyboard_input_listener_status);
|
||||
} else {
|
||||
keyboard_input_listener_.Bind(std::move(keyboard_input_listener));
|
||||
}
|
||||
// Connect to MouseInputListener
|
||||
fuchsia::ui::test::input::MouseInputListenerHandle mouse_input_listener;
|
||||
zx_status_t mouse_input_listener_status =
|
||||
dart_application_svc
|
||||
->Connect<fuchsia::ui::test::input::MouseInputListener>(
|
||||
mouse_input_listener.NewRequest());
|
||||
if (mouse_input_listener_status != ZX_OK) {
|
||||
FML_LOG(WARNING)
|
||||
<< "fuchsia::ui::test::input::MouseInputListener connection failed: "
|
||||
<< zx_status_get_string(mouse_input_listener_status);
|
||||
} else {
|
||||
mouse_input_listener_.Bind(std::move(mouse_input_listener));
|
||||
}
|
||||
}
|
||||
|
||||
// Finally! Register the native platform message handlers.
|
||||
RegisterPlatformMessageHandlers();
|
||||
}
|
||||
@ -162,6 +229,12 @@ void PlatformView::RegisterPlatformMessageHandlers() {
|
||||
platform_message_handlers_[kFuchsiaShaderWarmupChannel] =
|
||||
std::bind(&HandleFuchsiaShaderWarmupChannelPlatformMessage,
|
||||
on_shader_warmup_, std::placeholders::_1);
|
||||
platform_message_handlers_[kFuchsiaInputTestChannel] =
|
||||
std::bind(&PlatformView::HandleFuchsiaInputTestChannelPlatformMessage,
|
||||
this, std::placeholders::_1);
|
||||
platform_message_handlers_[kFuchsiaChildViewChannel] =
|
||||
std::bind(&PlatformView::HandleFuchsiaChildViewChannelPlatformMessage,
|
||||
this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
static flutter::PointerData::Change GetChangeFromPointerEventPhase(
|
||||
@ -673,4 +746,224 @@ bool PlatformView::HandleFuchsiaShaderWarmupChannelPlatformMessage(
|
||||
return true;
|
||||
}
|
||||
|
||||
// Channel handler for kFuchsiaInputTestChannel
|
||||
bool PlatformView::HandleFuchsiaInputTestChannelPlatformMessage(
|
||||
std::unique_ptr<flutter::PlatformMessage> message) {
|
||||
FML_DCHECK(message->channel() == kFuchsiaInputTestChannel);
|
||||
|
||||
const auto& data = message->data();
|
||||
rapidjson::Document document;
|
||||
document.Parse(reinterpret_cast<const char*>(data.GetMapping()),
|
||||
data.GetSize());
|
||||
if (document.HasParseError() || !document.IsObject()) {
|
||||
FML_LOG(ERROR) << "Could not parse document";
|
||||
return false;
|
||||
}
|
||||
auto root = document.GetObject();
|
||||
auto method = root.FindMember("method");
|
||||
if (method == root.MemberEnd() || !method->value.IsString()) {
|
||||
FML_LOG(ERROR) << "Missing method";
|
||||
return false;
|
||||
}
|
||||
|
||||
FML_LOG(INFO) << "fuchsia/input_test: method=" << method->value.GetString();
|
||||
|
||||
if (method->value == "TouchInputListener.ReportTouchInput") {
|
||||
if (!touch_input_listener_) {
|
||||
FML_LOG(ERROR) << "TouchInputListener not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
fuchsia::ui::test::input::TouchInputListenerReportTouchInputRequest request;
|
||||
CallWithMember<double>(
|
||||
root, "local_x", [&](double local_x) { request.set_local_x(local_x); });
|
||||
CallWithMember<double>(
|
||||
root, "local_y", [&](double local_y) { request.set_local_y(local_y); });
|
||||
CallWithMember<int64_t>(root, "time_received", [&](uint64_t time_received) {
|
||||
request.set_time_received(time_received);
|
||||
});
|
||||
CallWithMember<std::string>(root, "component_name",
|
||||
[&](std::string component_name) {
|
||||
request.set_component_name(component_name);
|
||||
});
|
||||
|
||||
touch_input_listener_->ReportTouchInput(std::move(request));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method->value == "KeyboardInputListener.ReportTextInput") {
|
||||
if (!keyboard_input_listener_) {
|
||||
FML_LOG(ERROR) << "KeyboardInputListener not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
fuchsia::ui::test::input::KeyboardInputListenerReportTextInputRequest
|
||||
request;
|
||||
CallWithMember<std::string>(
|
||||
root, "text", [&](std::string text) { request.set_text(text); });
|
||||
|
||||
keyboard_input_listener_->ReportTextInput(std::move(request));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method->value == "MouseInputListener.ReportMouseInput") {
|
||||
if (!mouse_input_listener_) {
|
||||
FML_LOG(ERROR) << "MouseInputListener not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
fuchsia::ui::test::input::MouseInputListenerReportMouseInputRequest request;
|
||||
CallWithMember<double>(
|
||||
root, "local_x", [&](double local_x) { request.set_local_x(local_x); });
|
||||
CallWithMember<double>(
|
||||
root, "local_y", [&](double local_y) { request.set_local_y(local_y); });
|
||||
CallWithMember<int64_t>(root, "time_received", [&](uint64_t time_received) {
|
||||
request.set_time_received(time_received);
|
||||
});
|
||||
CallWithMember<std::string>(root, "component_name",
|
||||
[&](std::string component_name) {
|
||||
request.set_component_name(component_name);
|
||||
});
|
||||
CallWithMember<int>(root, "buttons", [&](int button_mask) {
|
||||
std::vector<fuchsia::ui::test::input::MouseButton> buttons;
|
||||
if (button_mask & 1) {
|
||||
buttons.push_back(fuchsia::ui::test::input::MouseButton::FIRST);
|
||||
}
|
||||
if (button_mask & 2) {
|
||||
buttons.push_back(fuchsia::ui::test::input::MouseButton::SECOND);
|
||||
}
|
||||
if (button_mask & 4) {
|
||||
buttons.push_back(fuchsia::ui::test::input::MouseButton::THIRD);
|
||||
}
|
||||
request.set_buttons(buttons);
|
||||
});
|
||||
CallWithMember<std::string>(root, "phase", [&](std::string phase) {
|
||||
if (phase == "add") {
|
||||
request.set_phase(fuchsia::ui::test::input::MouseEventPhase::ADD);
|
||||
} else if (phase == "hover") {
|
||||
request.set_phase(fuchsia::ui::test::input::MouseEventPhase::HOVER);
|
||||
} else if (phase == "down") {
|
||||
request.set_phase(fuchsia::ui::test::input::MouseEventPhase::DOWN);
|
||||
} else if (phase == "move") {
|
||||
request.set_phase(fuchsia::ui::test::input::MouseEventPhase::MOVE);
|
||||
} else if (phase == "up") {
|
||||
request.set_phase(fuchsia::ui::test::input::MouseEventPhase::UP);
|
||||
} else {
|
||||
FML_LOG(ERROR) << "Unexpected mouse phase: " << phase;
|
||||
}
|
||||
});
|
||||
CallWithMember<double>(
|
||||
root, "wheel_x_physical_pixel", [&](double wheel_x_physical_pixel) {
|
||||
request.set_wheel_x_physical_pixel(wheel_x_physical_pixel);
|
||||
});
|
||||
CallWithMember<double>(
|
||||
root, "wheel_y_physical_pixel", [&](double wheel_y_physical_pixel) {
|
||||
request.set_wheel_y_physical_pixel(wheel_y_physical_pixel);
|
||||
});
|
||||
|
||||
mouse_input_listener_->ReportMouseInput(std::move(request));
|
||||
return true;
|
||||
}
|
||||
|
||||
FML_LOG(ERROR) << "fuchsia/input_test: unrecognized method "
|
||||
<< method->value.GetString();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Channel handler for kFuchsiaChildViewChannel
|
||||
bool PlatformView::HandleFuchsiaChildViewChannelPlatformMessage(
|
||||
std::unique_ptr<flutter::PlatformMessage> message) {
|
||||
FML_DCHECK(message->channel() == kFuchsiaChildViewChannel);
|
||||
|
||||
if (message->data().GetSize() != 1 ||
|
||||
(message->data().GetMapping()[0] != '0' &&
|
||||
message->data().GetMapping()[0] != '1')) {
|
||||
FML_LOG(ERROR) << kFuchsiaChildViewChannel
|
||||
<< " data must be '0' (for gfx) or '1' (for flatland).";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool flatland = message->data().GetMapping()[0] == '1';
|
||||
|
||||
if (!message->response()) {
|
||||
FML_LOG(ERROR) << kFuchsiaChildViewChannel
|
||||
<< " must have a response callback.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dart_application_svc_) {
|
||||
FML_LOG(ERROR) << "No service directory.";
|
||||
return false;
|
||||
}
|
||||
|
||||
fuchsia::ui::app::ViewProviderHandle view_provider_handle;
|
||||
zx_status_t status =
|
||||
dart_application_svc_->Connect(view_provider_handle.NewRequest());
|
||||
if (status != ZX_OK) {
|
||||
FML_LOG(ERROR) << "Failed to connect to view provider.";
|
||||
return false;
|
||||
}
|
||||
fuchsia::ui::app::ViewProviderPtr view_provider;
|
||||
view_provider.Bind(std::move(view_provider_handle));
|
||||
|
||||
zx::handle view_id;
|
||||
|
||||
if (flatland) {
|
||||
zx::channel view_tokens[2];
|
||||
fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
|
||||
fuchsia::ui::views::ViewCreationToken view_creation_token;
|
||||
status = zx::channel::create(0, &viewport_creation_token.value,
|
||||
&view_creation_token.value);
|
||||
if (status != ZX_OK) {
|
||||
FML_LOG(ERROR) << "Creating view tokens: "
|
||||
<< zx_status_get_string(status);
|
||||
return false;
|
||||
}
|
||||
|
||||
fuchsia::ui::app::CreateView2Args create_view_args;
|
||||
create_view_args.set_view_creation_token(std::move(view_creation_token));
|
||||
view_provider->CreateView2(std::move(create_view_args));
|
||||
|
||||
view_id = std::move(viewport_creation_token.value);
|
||||
} else {
|
||||
zx::eventpair view_tokens[2];
|
||||
status = zx::eventpair::create(0, &view_tokens[0], &view_tokens[1]);
|
||||
if (status != ZX_OK) {
|
||||
FML_LOG(ERROR) << "Creating view tokens: "
|
||||
<< zx_status_get_string(status);
|
||||
return false;
|
||||
}
|
||||
fuchsia::ui::views::ViewHolderToken view_holder_token;
|
||||
view_holder_token.value = std::move(view_tokens[0]);
|
||||
|
||||
zx::eventpair view_refs[2];
|
||||
status = zx::eventpair::create(0, &view_refs[0], &view_refs[1]);
|
||||
if (status != ZX_OK) {
|
||||
FML_LOG(ERROR) << "Creating view refs: " << zx_status_get_string(status);
|
||||
return false;
|
||||
}
|
||||
fuchsia::ui::views::ViewRefControl view_ref_control;
|
||||
view_refs[0].duplicate(ZX_DEFAULT_EVENTPAIR_RIGHTS & ~ZX_RIGHT_DUPLICATE,
|
||||
&view_ref_control.reference);
|
||||
fuchsia::ui::views::ViewRef view_ref;
|
||||
view_refs[1].duplicate(ZX_RIGHTS_BASIC, &view_ref.reference);
|
||||
|
||||
view_provider->CreateViewWithViewRef(std::move(view_tokens[1]),
|
||||
std::move(view_ref_control),
|
||||
std::move(view_ref));
|
||||
|
||||
view_id = std::move(view_holder_token.value);
|
||||
}
|
||||
|
||||
if (view_id) {
|
||||
message->response()->Complete(
|
||||
std::make_unique<fml::DataMapping>(std::to_string(view_id.release())
|
||||
|
||||
));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace flutter_runner
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <fuchsia/ui/input3/cpp/fidl.h>
|
||||
#include <fuchsia/ui/pointer/cpp/fidl.h>
|
||||
#include <fuchsia/ui/scenic/cpp/fidl.h>
|
||||
#include <fuchsia/ui/test/input/cpp/fidl.h>
|
||||
#include <lib/fidl/cpp/binding.h>
|
||||
#include <lib/fit/function.h>
|
||||
#include <lib/sys/cpp/service_directory.h>
|
||||
@ -84,7 +85,8 @@ class PlatformView : public flutter::PlatformView {
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
AwaitVsyncCallback await_vsync_callback,
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback);
|
||||
await_vsync_for_secondary_callback_callback,
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc);
|
||||
|
||||
~PlatformView() override;
|
||||
|
||||
@ -136,6 +138,14 @@ class PlatformView : public flutter::PlatformView {
|
||||
OnShaderWarmup on_shader_warmup,
|
||||
std::unique_ptr<flutter::PlatformMessage> message);
|
||||
|
||||
// Channel handler for kFuchsiaInputTestChannel.
|
||||
bool HandleFuchsiaInputTestChannelPlatformMessage(
|
||||
std::unique_ptr<flutter::PlatformMessage> message);
|
||||
|
||||
// Channel handler for kFuchsiaChildViewChannel.
|
||||
bool HandleFuchsiaChildViewChannelPlatformMessage(
|
||||
std::unique_ptr<flutter::PlatformMessage> message);
|
||||
|
||||
virtual void OnCreateView(ViewCallback on_view_created,
|
||||
int64_t view_id_raw,
|
||||
bool hit_testable,
|
||||
@ -186,6 +196,14 @@ class PlatformView : public flutter::PlatformView {
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback_;
|
||||
|
||||
// Proxies for input tests.
|
||||
fuchsia::ui::test::input::TouchInputListenerPtr touch_input_listener_;
|
||||
fuchsia::ui::test::input::KeyboardInputListenerPtr keyboard_input_listener_;
|
||||
fuchsia::ui::test::input::MouseInputListenerPtr mouse_input_listener_;
|
||||
|
||||
// Component's service directory.
|
||||
std::shared_ptr<sys::ServiceDirectory> dart_application_svc_;
|
||||
|
||||
fml::WeakPtrFactory<PlatformView> weak_factory_; // Must be the last member.
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
|
||||
|
||||
@ -331,7 +331,8 @@ class PlatformViewBuilder {
|
||||
std::move(on_create_surface_callback_),
|
||||
std::move(on_semantics_node_update_callback_),
|
||||
std::move(on_request_announce_callback_),
|
||||
std::move(on_shader_warmup_callback_), [](auto...) {}, [](auto...) {});
|
||||
std::move(on_shader_warmup_callback_), [](auto...) {}, [](auto...) {},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -436,7 +436,8 @@ class PlatformViewBuilder {
|
||||
std::move(on_create_surface_callback_),
|
||||
std::move(on_semantics_node_update_callback_),
|
||||
std::move(on_request_announce_callback_),
|
||||
std::move(on_shader_warmup_callback_), [](auto...) {}, [](auto...) {});
|
||||
std::move(on_shader_warmup_callback_), [](auto...) {}, [](auto...) {},
|
||||
nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -2,21 +2,19 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:io';
|
||||
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:fuchsia_services/services.dart';
|
||||
import 'package:vector_math/vector_math_64.dart' as vector_math_64;
|
||||
import 'package:zircon/zircon.dart';
|
||||
|
||||
final _argsCsvFilePath = '/config/data/args.csv';
|
||||
|
||||
void main(List<String> args) {
|
||||
void main(List<String> args) async {
|
||||
print('parent-view: starting');
|
||||
|
||||
args = args + _GetArgsFromConfigFile();
|
||||
@ -32,21 +30,12 @@ void main(List<String> args) {
|
||||
|
||||
TestApp app;
|
||||
final useFlatland = arguments['useFlatland'];
|
||||
if (useFlatland) {
|
||||
app = TestApp(
|
||||
ChildView(_launchFlatlandChildView()),
|
||||
showOverlay: arguments['showOverlay'],
|
||||
hitTestable: arguments['hitTestable'],
|
||||
focusable: arguments['focusable'],
|
||||
);
|
||||
} else {
|
||||
app = TestApp(
|
||||
ChildView.gfx(_launchGfxChildView()),
|
||||
showOverlay: arguments['showOverlay'],
|
||||
hitTestable: arguments['hitTestable'],
|
||||
focusable: arguments['focusable'],
|
||||
);
|
||||
}
|
||||
app = TestApp(
|
||||
ChildView(await _launchChildView(useFlatland)),
|
||||
showOverlay: arguments['showOverlay'],
|
||||
hitTestable: arguments['hitTestable'],
|
||||
focusable: arguments['focusable'],
|
||||
);
|
||||
|
||||
app.run();
|
||||
}
|
||||
@ -62,35 +51,33 @@ class TestApp {
|
||||
|
||||
Color _backgroundColor = _blue;
|
||||
|
||||
TestApp(
|
||||
this.childView,
|
||||
{this.showOverlay = false,
|
||||
this.hitTestable = true,
|
||||
this.focusable = true}) {
|
||||
}
|
||||
TestApp(this.childView,
|
||||
{this.showOverlay = false,
|
||||
this.hitTestable = true,
|
||||
this.focusable = true}) {}
|
||||
|
||||
void run() {
|
||||
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;
|
||||
}
|
||||
// Set up window allbacks.
|
||||
window.onPointerDataPacket = (PointerDataPacket packet) {
|
||||
for (final data in packet.data) {
|
||||
if (data.change == PointerChange.down) {
|
||||
this._backgroundColor = _black;
|
||||
}
|
||||
window.scheduleFrame();
|
||||
};
|
||||
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();
|
||||
});
|
||||
};
|
||||
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) {
|
||||
@ -114,18 +101,16 @@ class TestApp {
|
||||
// Alignment.center
|
||||
final windowCenter = windowSize.center(Offset.zero);
|
||||
final windowPhysicalCenter = window.physicalSize.center(Offset.zero);
|
||||
final childPhysicalOffset = windowPhysicalCenter - childPhysicalSize.center(Offset.zero);
|
||||
final childPhysicalOffset =
|
||||
windowPhysicalCenter - childPhysicalSize.center(Offset.zero);
|
||||
|
||||
sceneBuilder
|
||||
..pushTransform(
|
||||
vector_math_64.Matrix4.translationValues(childPhysicalOffset.dx,
|
||||
childPhysicalOffset.dy,
|
||||
0.0).storage)
|
||||
..pushTransform(vector_math_64.Matrix4.translationValues(
|
||||
childPhysicalOffset.dx, childPhysicalOffset.dy, 0.0)
|
||||
.storage)
|
||||
..addPlatformView(childView.viewId,
|
||||
width: childPhysicalSize.width,
|
||||
height: childPhysicalSize.height)
|
||||
..pop()
|
||||
;
|
||||
width: childPhysicalSize.width, height: childPhysicalSize.height)
|
||||
..pop();
|
||||
|
||||
if (showOverlay) {
|
||||
final containerSize = windowSize * .66;
|
||||
@ -135,15 +120,16 @@ class TestApp {
|
||||
final overlaySize = containerSize * 0.5;
|
||||
// Alignment.topRight
|
||||
final overlayOffset = Offset(
|
||||
containerOffset.dx + containerSize.width - overlaySize.width,
|
||||
containerOffset.dy);
|
||||
containerOffset.dx + containerSize.width - overlaySize.width,
|
||||
containerOffset.dy);
|
||||
|
||||
final overlayPhysicalSize = overlaySize * pixelRatio;
|
||||
final overlayPhysicalOffset = overlayOffset * pixelRatio;
|
||||
final overlayPhysicalBounds = overlayPhysicalOffset & overlayPhysicalSize;
|
||||
|
||||
final recorder = PictureRecorder();
|
||||
final overlayCullRect = Offset.zero & overlayPhysicalSize; // in canvas physical coordinates
|
||||
final overlayCullRect =
|
||||
Offset.zero & overlayPhysicalSize; // in canvas physical coordinates
|
||||
final canvas = Canvas(recorder, overlayCullRect);
|
||||
canvas.scale(pixelRatio);
|
||||
final paint = Paint()..color = Color.fromARGB(255, 0, 255, 0);
|
||||
@ -152,8 +138,7 @@ class TestApp {
|
||||
sceneBuilder
|
||||
..pushClipRect(overlayPhysicalBounds) // in window physical coordinates
|
||||
..addPicture(overlayPhysicalOffset, overlayPicture)
|
||||
..pop()
|
||||
;
|
||||
..pop();
|
||||
}
|
||||
sceneBuilder.pop();
|
||||
|
||||
@ -162,22 +147,12 @@ class TestApp {
|
||||
}
|
||||
|
||||
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(this.viewId);
|
||||
|
||||
ChildView.gfx(this.viewHolderToken) : viewportCreationToken = null, viewId = viewHolderToken.value.handle.handle {
|
||||
assert(viewId != null);
|
||||
}
|
||||
|
||||
void create(
|
||||
bool hitTestable,
|
||||
bool focusable,
|
||||
PlatformMessageResponseCallback callback) {
|
||||
void create(bool hitTestable, bool focusable,
|
||||
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-view2 in the scene.
|
||||
@ -195,59 +170,31 @@ class ChildView {
|
||||
],
|
||||
};
|
||||
|
||||
final ByteData createViewMessage = utf8.encoder.convert(
|
||||
json.encode(<String, Object>{
|
||||
'method': 'View.create',
|
||||
'args': args,
|
||||
})
|
||||
).buffer.asByteData();
|
||||
final ByteData createViewMessage = utf8.encoder
|
||||
.convert(json.encode(<String, Object>{
|
||||
'method': 'View.create',
|
||||
'args': args,
|
||||
}))
|
||||
.buffer
|
||||
.asByteData();
|
||||
|
||||
final platformViewsChannel = 'flutter/platform_views';
|
||||
|
||||
PlatformDispatcher.instance.sendPlatformMessage(
|
||||
platformViewsChannel,
|
||||
createViewMessage,
|
||||
callback);
|
||||
PlatformDispatcher.instance
|
||||
.sendPlatformMessage(platformViewsChannel, createViewMessage, callback);
|
||||
}
|
||||
}
|
||||
|
||||
ViewportCreationToken _launchFlatlandChildView() {
|
||||
ViewProviderProxy viewProvider = ViewProviderProxy();
|
||||
Incoming.fromSvcPath()
|
||||
..connectToService(viewProvider)
|
||||
..close();
|
||||
Future<int> _launchChildView(bool useFlatland) async {
|
||||
final message = Int8List.fromList([useFlatland ? 0x31 : 0x30]);
|
||||
final completer = new Completer<ByteData>();
|
||||
PlatformDispatcher.instance.sendPlatformMessage(
|
||||
'fuchsia/child_view', ByteData.sublistView(message), (ByteData reply) {
|
||||
completer.complete(reply);
|
||||
});
|
||||
|
||||
final viewTokens = ChannelPair();
|
||||
assert(viewTokens.status == ZX.OK);
|
||||
final viewportCreationToken = ViewportCreationToken(value: viewTokens.first);
|
||||
final viewCreationToken = ViewCreationToken(value: viewTokens.second);
|
||||
|
||||
final createViewArgs = CreateView2Args(viewCreationToken: viewCreationToken);
|
||||
viewProvider.createView2(createViewArgs);
|
||||
viewProvider.ctrl.close();
|
||||
|
||||
return viewportCreationToken;
|
||||
}
|
||||
|
||||
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 viewRefs = EventPairPair();
|
||||
assert(viewRefs.status == ZX.OK);
|
||||
final viewRefControl = ViewRefControl(reference: viewRefs.first.duplicate(ZX.DEFAULT_EVENTPAIR_RIGHTS & ~ZX.RIGHT_DUPLICATE));
|
||||
final viewRef = ViewRef(reference: viewRefs.second.duplicate(ZX.RIGHTS_BASIC));
|
||||
|
||||
viewProvider.createViewWithViewRef(viewTokens.second, viewRefControl, viewRef);
|
||||
viewProvider.ctrl.close();
|
||||
|
||||
return viewHolderToken;
|
||||
return int.parse(
|
||||
ascii.decode(((await completer.future).buffer.asUint8List())));
|
||||
}
|
||||
|
||||
List<String> _GetArgsFromConfigFile() {
|
||||
|
||||
@ -14,9 +14,7 @@ dart_library("lib") {
|
||||
|
||||
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",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,6 @@ import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_mouse;
|
||||
import 'package:fuchsia_services/services.dart';
|
||||
import 'package:zircon/zircon.dart';
|
||||
|
||||
void main() {
|
||||
@ -16,38 +14,6 @@ void main() {
|
||||
app.run();
|
||||
}
|
||||
|
||||
List<test_mouse.MouseButton> getPressedButtons(int buttons) {
|
||||
var pressed_buttons = <test_mouse.MouseButton>[];
|
||||
if (buttons & 0x1 != 0) {
|
||||
pressed_buttons.add(test_mouse.MouseButton.first);
|
||||
}
|
||||
if (buttons & (0x1 >> 1) != 0) {
|
||||
pressed_buttons.add(test_mouse.MouseButton.second);
|
||||
}
|
||||
if (buttons & (0x1 >> 2) != 0) {
|
||||
pressed_buttons.add(test_mouse.MouseButton.third);
|
||||
}
|
||||
|
||||
return pressed_buttons;
|
||||
}
|
||||
|
||||
test_mouse.MouseEventPhase getPhase(String event_type) {
|
||||
switch (event_type) {
|
||||
case 'add':
|
||||
return test_mouse.MouseEventPhase.add;
|
||||
case 'hover':
|
||||
return test_mouse.MouseEventPhase.hover;
|
||||
case 'down':
|
||||
return test_mouse.MouseEventPhase.down;
|
||||
case 'move':
|
||||
return test_mouse.MouseEventPhase.move;
|
||||
case 'up':
|
||||
return test_mouse.MouseEventPhase.up;
|
||||
default:
|
||||
print('Invalid event type: ${event_type}');
|
||||
}
|
||||
}
|
||||
|
||||
class MyApp {
|
||||
static const _red = Color.fromARGB(255, 244, 67, 54);
|
||||
static const _orange = Color.fromARGB(255, 255, 152, 0);
|
||||
@ -67,11 +33,8 @@ class MyApp {
|
||||
|
||||
// Each tap will increment the counter, we then determine what color to choose
|
||||
int _touchCounter = 0;
|
||||
final _responseListener = test_mouse.MouseInputListenerProxy();
|
||||
|
||||
void run() {
|
||||
Incoming.fromSvcPath()
|
||||
..connectToService(_responseListener);
|
||||
// Set up window callbacks.
|
||||
window.onPointerDataPacket = (PointerDataPacket packet) {
|
||||
this.pointerDataPacket(packet);
|
||||
@ -122,28 +85,45 @@ class MyApp {
|
||||
_touchCounter++;
|
||||
}
|
||||
|
||||
// Incoming.fromSvcPath()
|
||||
// ..connectToService(_responseListener)
|
||||
// ..close();
|
||||
|
||||
_respond(test_mouse.MouseInputListenerReportMouseInputRequest(
|
||||
_reportMouseInput(
|
||||
localX: data.physicalX,
|
||||
localY: data.physicalY,
|
||||
buttons: getPressedButtons(data.buttons),
|
||||
phase: getPhase(data.change.name),
|
||||
buttons: data.buttons,
|
||||
phase: data.change.name,
|
||||
timeReceived: nowNanos,
|
||||
wheelXPhysicalPixel: data.scrollDeltaX,
|
||||
wheelYPhysicalPixel: data.scrollDeltaY,
|
||||
componentName: 'mouse-input-view',
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
window.scheduleFrame();
|
||||
}
|
||||
|
||||
void _respond(test_mouse.MouseInputListenerReportMouseInputRequest request) async {
|
||||
void _reportMouseInput(
|
||||
{double localX,
|
||||
double localY,
|
||||
int timeReceived,
|
||||
int buttons,
|
||||
String phase,
|
||||
double wheelXPhysicalPixel,
|
||||
double wheelYPhysicalPixel}) {
|
||||
print('mouse-input-view reporting mouse input to MouseInputListener');
|
||||
await _responseListener.reportMouseInput(request);
|
||||
final message = utf8.encoder
|
||||
.convert(json.encode({
|
||||
'method': 'MouseInputListener.ReportMouseInput',
|
||||
'local_x': localX,
|
||||
'local_y': localY,
|
||||
'time_received': timeReceived,
|
||||
'component_name': 'touch-input-view',
|
||||
'buttons': buttons,
|
||||
'phase': 'asdf',
|
||||
'wheel_x_physical_pixel': wheelXPhysicalPixel,
|
||||
'wheel_y_physical_pixel': wheelYPhysicalPixel,
|
||||
}))
|
||||
.buffer
|
||||
.asByteData();
|
||||
PlatformDispatcher.instance
|
||||
.sendPlatformMessage('fuchsia/input_test', message, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,12 +12,7 @@ dart_library("lib") {
|
||||
testonly = true
|
||||
package_name = "text-input-view"
|
||||
sources = [ "text_input_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",
|
||||
]
|
||||
deps = [ "//flutter/shell/platform/fuchsia/dart:args" ]
|
||||
}
|
||||
|
||||
flutter_component("component") {
|
||||
|
||||
@ -10,10 +10,6 @@ import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:fidl_fuchsia_ui_test_input/fidl_async.dart' as test_text;
|
||||
import 'package:fuchsia_services/services.dart';
|
||||
import 'package:zircon/zircon.dart';
|
||||
|
||||
// Corresponds to the USB HID values provided in fidl.fuchsia.input
|
||||
// https://fuchsia.dev/reference/fidl/fuchsia.input
|
||||
final Map<int, String> hidToKey = {
|
||||
@ -39,11 +35,7 @@ class TestApp {
|
||||
static const _yellow = Color.fromARGB(255, 255, 255, 0);
|
||||
Color _backgroundColor = _yellow;
|
||||
|
||||
final _responseListener = test_text.KeyboardInputListenerProxy();
|
||||
|
||||
void run() {
|
||||
// Connect to keyboard input response listener
|
||||
Incoming.fromSvcPath().connectToService(_responseListener);
|
||||
// Set up window callbacks
|
||||
window.onPlatformMessage = (String name, ByteData data, PlatformMessageResponseCallback callback) {
|
||||
this.decodeAndReportPlatformMessage(name, data);
|
||||
@ -89,17 +81,20 @@ class TestApp {
|
||||
|
||||
if (name == "flutter/keyevent" && decodedJson["type"] == "keydown") {
|
||||
if (hidToKey[decodedJson["hidUsage"]] != null) {
|
||||
await _respond(test_text.KeyboardInputListenerReportTextInputRequest(
|
||||
text: hidToKey[decodedJson["hidUsage"]],
|
||||
));
|
||||
_reportTextInput(hidToKey[decodedJson["hidUsage"]]);
|
||||
}
|
||||
}
|
||||
|
||||
window.scheduleFrame();
|
||||
}
|
||||
|
||||
void _respond(test_text.KeyboardInputListenerReportTextInputRequest request) async {
|
||||
void _reportTextInput(String text) {
|
||||
print('text-input-view reporting keyboard input to KeyboardInputListener');
|
||||
await _responseListener.reportTextInput(request);
|
||||
|
||||
final message = utf8.encoder.convert(json.encode({
|
||||
'method': 'KeyboardInputListener.ReportTextInput',
|
||||
'text': text,
|
||||
})).buffer.asByteData();
|
||||
PlatformDispatcher.instance.sendPlatformMessage('fuchsia/input_test', message, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,12 +15,7 @@ dart_library("lib") {
|
||||
deps = [
|
||||
"//flutter/shell/platform/fuchsia/dart:args",
|
||||
"//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.views",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -2,22 +2,19 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:io';
|
||||
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';
|
||||
|
||||
final _argsCsvFilePath = '/config/data/args.csv';
|
||||
|
||||
void main(List<String> args) {
|
||||
void main(List<String> args) async {
|
||||
print('Launching embedding-flutter-view');
|
||||
|
||||
args = args + _GetArgsFromConfigFile();
|
||||
@ -33,7 +30,7 @@ void main(List<String> args) {
|
||||
|
||||
// TODO(fxbug.dev/125514): Support Flatland Child View.
|
||||
TestApp app = TestApp(
|
||||
ChildView.gfx(_launchGfxChildView()),
|
||||
ChildView(await _launchChildView(false)),
|
||||
showOverlay: arguments['showOverlay'],
|
||||
hitTestable: arguments['hitTestable'],
|
||||
focusable: arguments['focusable'],
|
||||
@ -50,7 +47,6 @@ class TestApp {
|
||||
final bool showOverlay;
|
||||
final bool hitTestable;
|
||||
final bool focusable;
|
||||
final _responseListener = test_touch.TouchInputListenerProxy();
|
||||
|
||||
Color _backgroundColor = _blue;
|
||||
|
||||
@ -159,40 +155,34 @@ class TestApp {
|
||||
}
|
||||
|
||||
if (data.change == PointerChange.down || data.change == PointerChange.move) {
|
||||
Incoming.fromSvcPath()
|
||||
..connectToService(_responseListener)
|
||||
..close();
|
||||
|
||||
_respond(test_touch.TouchInputListenerReportTouchInputRequest(
|
||||
_reportTouchInput(
|
||||
localX: data.physicalX,
|
||||
localY: data.physicalY,
|
||||
timeReceived: nowNanos,
|
||||
componentName: 'embedding-flutter-view',
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
window.scheduleFrame();
|
||||
}
|
||||
|
||||
void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async {
|
||||
void _reportTouchInput({double localX, double localY, int timeReceived}) {
|
||||
print('embedding-flutter-view reporting touch input to TouchInputListener');
|
||||
await _responseListener.reportTouchInput(request);
|
||||
final message = utf8.encoder.convert(json.encode({
|
||||
'method': 'TouchInputListener.ReportTouchInput',
|
||||
'local_x': localX,
|
||||
'local_y': localY,
|
||||
'time_received': timeReceived,
|
||||
'component_name': 'embedding-flutter-view',
|
||||
})).buffer.asByteData();
|
||||
PlatformDispatcher.instance.sendPlatformMessage('fuchsia/input_test', message, null);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
ChildView(this.viewId);
|
||||
|
||||
void create(
|
||||
bool hitTestable,
|
||||
@ -230,27 +220,19 @@ class ChildView {
|
||||
}
|
||||
}
|
||||
|
||||
ViewHolderToken _launchGfxChildView() {
|
||||
ViewProviderProxy viewProvider = ViewProviderProxy();
|
||||
Incoming.fromSvcPath()
|
||||
..connectToService(viewProvider)
|
||||
..close();
|
||||
Future<int> _launchChildView(bool useFlatland) async {
|
||||
final message = Int8List.fromList([useFlatland ? 0x31 : 0x30]);
|
||||
final completer = new Completer<ByteData>();
|
||||
PlatformDispatcher.instance.sendPlatformMessage(
|
||||
'fuchsia/child_view', ByteData.sublistView(message), (ByteData reply) {
|
||||
completer.complete(reply);
|
||||
});
|
||||
|
||||
final viewTokens = EventPairPair();
|
||||
assert(viewTokens.status == ZX.OK);
|
||||
final viewHolderToken = ViewHolderToken(value: viewTokens.first);
|
||||
|
||||
final viewRefs = EventPairPair();
|
||||
assert(viewRefs.status == ZX.OK);
|
||||
final viewRefControl = ViewRefControl(reference: viewRefs.first.duplicate(ZX.DEFAULT_EVENTPAIR_RIGHTS & ~ZX.RIGHT_DUPLICATE));
|
||||
final viewRef = ViewRef(reference: viewRefs.second.duplicate(ZX.RIGHTS_BASIC));
|
||||
|
||||
viewProvider.createViewWithViewRef(viewTokens.second, viewRefControl, viewRef);
|
||||
viewProvider.ctrl.close();
|
||||
|
||||
return viewHolderToken;
|
||||
return int.parse(
|
||||
ascii.decode(((await completer.future).buffer.asUint8List())));
|
||||
}
|
||||
|
||||
|
||||
List<String> _GetArgsFromConfigFile() {
|
||||
List<String> args;
|
||||
final f = File(_argsCsvFilePath);
|
||||
|
||||
@ -14,9 +14,7 @@ dart_library("lib") {
|
||||
|
||||
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",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,6 @@ import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
|
||||
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() {
|
||||
@ -22,8 +20,6 @@ class TestApp {
|
||||
|
||||
Color _backgroundColor = _pink;
|
||||
|
||||
final _responseListener = test_touch.TouchInputListenerProxy();
|
||||
|
||||
void run() {
|
||||
// Set up window callbacks.
|
||||
window.onPointerDataPacket = (PointerDataPacket packet) {
|
||||
@ -74,24 +70,26 @@ class TestApp {
|
||||
}
|
||||
|
||||
if (data.change == PointerChange.down || data.change == PointerChange.move) {
|
||||
Incoming.fromSvcPath()
|
||||
..connectToService(_responseListener)
|
||||
..close();
|
||||
|
||||
_respond(test_touch.TouchInputListenerReportTouchInputRequest(
|
||||
_reportTouchInput(
|
||||
localX: data.physicalX,
|
||||
localY: data.physicalY,
|
||||
timeReceived: nowNanos,
|
||||
componentName: 'touch-input-view',
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
window.scheduleFrame();
|
||||
}
|
||||
|
||||
void _respond(test_touch.TouchInputListenerReportTouchInputRequest request) async {
|
||||
void _reportTouchInput({double localX, double localY, int timeReceived}) {
|
||||
print('touch-input-view reporting touch input to TouchInputListener');
|
||||
await _responseListener.reportTouchInput(request);
|
||||
final message = utf8.encoder.convert(json.encode({
|
||||
'method': 'TouchInputListener.ReportTouchInput',
|
||||
'local_x': localX,
|
||||
'local_y': localY,
|
||||
'time_received': timeReceived,
|
||||
'component_name': 'touch-input-view',
|
||||
})).buffer.asByteData();
|
||||
PlatformDispatcher.instance.sendPlatformMessage('fuchsia/input_test', message, null);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user