[fuchsia][scenic] Add support for viewConnected and viewDisconnected (flutter/engine#36298)

signals in flatland.

This PR adds support for sending 'View.viewConnected' platform message
when a view gets created and 'View.viewDisconnected' signal when a view
gets destroyed.

Test: ffx test run "fuchsia-pkg://fuchsia.com/flutter_runner_tests#meta/flutter_runner_tests.cm"

Bug: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=93452
This commit is contained in:
Shivesh Ganju 2022-09-20 17:53:27 -04:00 committed by GitHub
parent 74ec47aa10
commit f73cf637fd
3 changed files with 105 additions and 21 deletions

View File

@ -153,7 +153,9 @@ void FlatlandPlatformView::OnChildViewViewRef(
fuchsia::ui::views::ViewRef view_ref_clone;
fidl::Clone(view_ref, &view_ref_clone);
pointer_injector_delegate_->OnCreateView(view_id, std::move(view_ref_clone));
OnChildViewConnected(content_id);
// TODO(http://fxbug.dev/109948): Remove the following GetViewRef call.
child_view_info_.at(content_id)
.child_view_watcher->GetViewRef(
[this, content_id, view_id](fuchsia::ui::views::ViewRef view_ref) {
@ -182,7 +184,7 @@ void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
FML_CHECK(child_view_watcher);
child_view_watcher.set_error_handler(
[weak, view_id](zx_status_t status) {
[weak, view_id, content_id](zx_status_t status) {
FML_LOG(ERROR) << "Interface error on: ChildViewWatcher status: "
<< status;
@ -195,6 +197,8 @@ void FlatlandPlatformView::OnCreateView(ViewCallback on_view_created,
// Disconnected views cannot listen to pointer events.
weak->pointer_injector_delegate_->OnDestroyView(view_id);
weak->OnChildViewDisconnected(content_id.value);
});
platform_task_runner->PostTask(
@ -246,6 +250,7 @@ void FlatlandPlatformView::OnDisposeView(int64_t view_id_raw) {
}
FML_DCHECK(weak->child_view_info_.count(content_id.value) == 1);
weak->OnChildViewDisconnected(content_id.value);
weak->child_view_info_.erase(content_id.value);
weak->focus_delegate_->OnDisposeChildView(view_id_raw);
weak->pointer_injector_delegate_->OnDestroyView(view_id_raw);
@ -254,4 +259,38 @@ void FlatlandPlatformView::OnDisposeView(int64_t view_id_raw) {
on_destroy_view_callback_(view_id_raw, std::move(on_view_unbound));
}
void FlatlandPlatformView::OnChildViewConnected(uint64_t content_id) {
FML_CHECK(child_view_info_.count(content_id) == 1);
std::ostringstream out;
out << "{"
<< "\"method\":\"View.viewConnected\","
<< "\"args\":{"
<< " \"viewId\":" << child_view_info_.at(content_id).view_id << " }"
<< "}";
auto call = out.str();
std::unique_ptr<flutter::PlatformMessage> message =
std::make_unique<flutter::PlatformMessage>(
"flutter/platform_views",
fml::MallocMapping::Copy(call.c_str(), call.size()), nullptr);
DispatchPlatformMessage(std::move(message));
}
void FlatlandPlatformView::OnChildViewDisconnected(uint64_t content_id) {
FML_CHECK(child_view_info_.count(content_id) == 1);
std::ostringstream out;
out << "{"
<< "\"method\":\"View.viewDisconnected\","
<< "\"args\":{"
<< " \"viewId\":" << child_view_info_.at(content_id).view_id << " }"
<< "}";
auto call = out.str();
std::unique_ptr<flutter::PlatformMessage> message =
std::make_unique<flutter::PlatformMessage>(
"flutter/platform_views",
fml::MallocMapping::Copy(call.c_str(), call.size()), nullptr);
DispatchPlatformMessage(std::move(message));
}
} // namespace flutter_runner

View File

@ -65,6 +65,15 @@ class FlatlandPlatformView final : public flutter_runner::PlatformView {
bool focusable) override;
void OnDisposeView(int64_t view_id_raw) override;
// Sends a 'View.viewConnected' platform message over 'flutter/platform_views'
// channel when a view gets created.
void OnChildViewConnected(uint64_t content_id);
// Sends a 'View.viewDisconnected' platform message over
// 'flutter/platform_views' channel when a view gets destroyed or the child
// view watcher channel of a view closes.
void OnChildViewDisconnected(uint64_t content_id);
// child_view_ids_ maintains a persistent mapping from Flatland ContentId's to
// flutter view ids, which are really zx_handle_t of ViewCreationToken.
struct ChildViewInfo {

View File

@ -750,6 +750,7 @@ TEST_F(FlatlandPlatformViewTests, EnableWireframeTest) {
// "flutter/platform_views" channel for Createview.
TEST_F(FlatlandPlatformViewTests, CreateViewTest) {
MockPlatformViewDelegate delegate;
const uint64_t view_id = 42;
flutter::TaskRunners task_runners =
flutter::TaskRunners("test_runners", // label
flutter_runner::CreateFMLTaskRunner(
@ -784,25 +785,41 @@ TEST_F(FlatlandPlatformViewTests, CreateViewTest) {
EXPECT_TRUE(base_view);
// JSON for the message to be passed into the PlatformView.
const uint8_t txt[] =
"{"
" \"method\":\"View.create\","
" \"args\": {"
" \"viewId\":42,"
" \"hitTestable\":true,"
" \"focusable\":true"
" }"
"}";
std::ostringstream create_view_message;
create_view_message << "{"
<< " \"method\":\"View.create\","
<< " \"args\":{"
<< " \"viewId\":" << view_id << ","
<< " \"hitTestable\":true,"
<< " \"focusable\":true"
<< " }"
<< "}";
std::string create_view_call = create_view_message.str();
std::unique_ptr<flutter::PlatformMessage> message =
std::make_unique<flutter::PlatformMessage>(
"flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
"flutter/platform_views",
fml::MallocMapping::Copy(create_view_call.c_str(),
create_view_call.size()),
fml::RefPtr<flutter::PlatformMessageResponse>());
base_view->HandlePlatformMessage(std::move(message));
RunLoopUntilIdle();
EXPECT_TRUE(create_view_called);
// Platform view forwards the 'View.viewConnected' message on the
// 'flutter/platform_views' channel when a view gets created.
std::ostringstream view_connected_expected_out;
view_connected_expected_out << "{"
<< "\"method\":\"View.viewConnected\","
<< "\"args\":{"
<< " \"viewId\":" << view_id << " }"
<< "}";
ASSERT_NE(delegate.message(), nullptr);
EXPECT_EQ(view_connected_expected_out.str(),
ToString(delegate.message()->data()));
}
// This test makes sure that the PlatformView forwards messages on the
@ -924,6 +941,8 @@ TEST_F(FlatlandPlatformViewTests, UpdateViewTest) {
// "flutter/platform_views" channel for DestroyView.
TEST_F(FlatlandPlatformViewTests, DestroyViewTest) {
MockPlatformViewDelegate delegate;
const uint64_t view_id = 42;
flutter::TaskRunners task_runners =
flutter::TaskRunners("test_runners", // label
flutter_runner::CreateFMLTaskRunner(
@ -970,7 +989,7 @@ TEST_F(FlatlandPlatformViewTests, DestroyViewTest) {
create_message << "{"
<< " \"method\":\"View.create\","
<< " \"args\": {"
<< " \"viewId\":42,"
<< " \"viewId\":" << view_id << ","
<< " \"hitTestable\":true,"
<< " \"focusable\":true"
<< " }"
@ -981,24 +1000,41 @@ TEST_F(FlatlandPlatformViewTests, DestroyViewTest) {
"flutter/platform_views", create_message.str()));
RunLoopUntilIdle();
// JSON for the message to be passed into the PlatformView.
const uint8_t txt[] =
"{"
" \"method\":\"View.dispose\","
" \"args\": {"
" \"viewId\":42"
" }"
"}";
delegate.Reset();
// JSON for the message to be passed into the PlatformView.
std::ostringstream dispose_message;
dispose_message << "{"
<< " \"method\":\"View.dispose\","
<< " \"args\": {"
<< " \"viewId\":" << view_id << " }"
<< "}";
std::string dispose_view_call = dispose_message.str();
std::unique_ptr<flutter::PlatformMessage> message =
std::make_unique<flutter::PlatformMessage>(
"flutter/platform_views", fml::MallocMapping::Copy(txt, sizeof(txt)),
"flutter/platform_views",
fml::MallocMapping::Copy(dispose_view_call.c_str(),
dispose_view_call.size()),
fml::RefPtr<flutter::PlatformMessageResponse>());
base_view->HandlePlatformMessage(std::move(message));
RunLoopUntilIdle();
EXPECT_TRUE(destroy_view_called);
// Platform view forwards the 'View.viewDisconnected' message on the
// 'flutter/platform_views' channel when a view gets destroyed.
std::ostringstream view_disconnected_expected_out;
view_disconnected_expected_out << "{"
<< "\"method\":\"View.viewDisconnected\","
<< "\"args\":{"
<< " \"viewId\":" << view_id << " }"
<< "}";
ASSERT_NE(delegate.message(), nullptr);
EXPECT_EQ(view_disconnected_expected_out.str(),
ToString(delegate.message()->data()));
}
// This test makes sure that the PlatformView forwards messages on the