Skip to content

Commit 3d49768

Browse files
authored
[fuchsia] add input shield to Flatland (flutter#31119)
Currenty this is a no-op on Flatland. This work is part of the effort to enable hit testing on Flatland, after a couple CLs land platform-side. Test: unittests and manual testing Bug: fxbug.dev/92165
1 parent d43a325 commit 3d49768

File tree

6 files changed

+175
-14
lines changed

6 files changed

+175
-14
lines changed

shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,14 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
272272
flatland_layers_[flatland_layer_index].transform_id);
273273
child_transforms_.emplace_back(
274274
flatland_layers_[flatland_layer_index].transform_id);
275+
276+
// Attach full-screen hit testing shield.
277+
flatland_->flatland()->SetHitRegions(
278+
flatland_layers_[flatland_layer_index].transform_id,
279+
{{{0, 0, std::numeric_limits<float>::max(),
280+
std::numeric_limits<float>::max()},
281+
fuchsia::ui::composition::HitTestInteraction::
282+
SEMANTICALLY_INVISIBLE}});
275283
}
276284

277285
// Reset for the next pass:

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,29 @@ void FakeFlatland::ReleaseImage(fuchsia::ui::composition::ContentId image_id) {
766766
pending_graph_.content_map.erase(found_content);
767767
}
768768

769+
void FakeFlatland::SetHitRegions(
770+
fuchsia::ui::composition::TransformId transform_id,
771+
std::vector<fuchsia::ui::composition::HitRegion> regions) {
772+
if (transform_id.value == 0) {
773+
// TODO(fxb/85619): Raise a FlatlandError here
774+
FML_CHECK(false)
775+
<< "FakeFlatland::SetTranslation: TransformId 0 is invalid.";
776+
return;
777+
}
778+
779+
auto found_transform = pending_graph_.transform_map.find(transform_id.value);
780+
if (found_transform == pending_graph_.transform_map.end()) {
781+
// TODO(fxb/85619): Raise a FlatlandError here
782+
FML_CHECK(false) << "FakeFlatland::SetTranslation: TransformId "
783+
<< transform_id.value << " does not exist.";
784+
return;
785+
}
786+
787+
auto& transform = found_transform->second;
788+
FML_CHECK(transform);
789+
transform->num_hit_regions = regions.size();
790+
}
791+
769792
void FakeFlatland::Clear() {
770793
parents_map_.clear();
771794
pending_graph_.Clear();

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ class FakeFlatland
297297
// |fuchsia::ui::composition::Flatland|
298298
void ReleaseImage(fuchsia::ui::composition::ContentId image_id) override;
299299

300+
// |fuchsia::ui::composition::Flatland|
301+
void SetHitRegions(
302+
fuchsia::ui::composition::TransformId transform_id,
303+
std::vector<fuchsia::ui::composition::HitRegion> regions) override;
304+
300305
// |fuchsia::ui::composition::Flatland|
301306
void Clear() override;
302307

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland_types.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ std::shared_ptr<FakeTransform> CloneFakeTransform(
7070
.children = CloneFakeTransformVector(
7171
transform->children, transform_cache),
7272
.content = CloneFakeContent(transform->content),
73+
.num_hit_regions = transform->num_hit_regions,
7374
}));
7475
FML_CHECK(success);
7576

@@ -132,7 +133,8 @@ bool FakeImage::operator==(const FakeImage& other) const {
132133
bool FakeTransform::operator==(const FakeTransform& other) const {
133134
return id == other.id && translation == other.translation &&
134135
clip_bounds == other.clip_bounds && orientation == other.orientation &&
135-
children == other.children && content == other.content;
136+
children == other.children && content == other.content &&
137+
num_hit_regions == other.num_hit_regions;
136138
}
137139

138140
bool FakeGraph::operator==(const FakeGraph& other) const {

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ struct FakeTransform {
180180

181181
std::vector<std::shared_ptr<FakeTransform>> children;
182182
std::shared_ptr<FakeContent> content;
183+
size_t num_hit_regions;
183184
};
184185

185186
struct FakeGraph {

shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc

Lines changed: 135 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ Matcher<FakeGraph> IsFlutterGraph(
217217
/*id*/ _, FakeTransform::kDefaultTranslation,
218218
FakeTransform::kDefaultClipBounds, FakeTransform::kDefaultOrientation,
219219
/*children*/ ElementsAreArray(layer_matchers),
220-
/*content*/ Eq(nullptr))),
220+
/*content*/ Eq(nullptr), /*num_hit_regions*/ _)),
221221
Eq(FakeView{
222222
.view_token = viewport_token_koids.second,
223223
.view_ref = view_ref_koids.first,
@@ -232,7 +232,8 @@ Matcher<FakeGraph> IsFlutterGraph(
232232

233233
Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
234234
const fuchsia::math::SizeU& layer_size,
235-
fuchsia::ui::composition::BlendMode blend_mode) {
235+
fuchsia::ui::composition::BlendMode blend_mode,
236+
size_t num_hit_regions) {
236237
return Pointee(FieldsAre(
237238
/*id*/ _, FakeTransform::kDefaultTranslation,
238239
FakeTransform::kDefaultClipBounds, FakeTransform::kDefaultOrientation,
@@ -242,7 +243,8 @@ Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
242243
/*id*/ _, IsImageProperties(layer_size),
243244
FakeImage::kDefaultSampleRegion, layer_size,
244245
FakeImage::kDefaultOpacity, blend_mode,
245-
/*buffer_import_token*/ _, /*vmo_index*/ 0)))));
246+
/*buffer_import_token*/ _, /*vmo_index*/ 0))),
247+
num_hit_regions));
246248
}
247249

248250
Matcher<std::shared_ptr<FakeTransform>> IsViewportLayer(
@@ -257,7 +259,8 @@ Matcher<std::shared_ptr<FakeTransform>> IsViewportLayer(
257259
Pointee(VariantWith<FakeViewport>(FieldsAre(
258260
/* id */ _, IsViewportProperties(view_logical_size),
259261
/* viewport_token */ GetKoids(view_token).second,
260-
/* child_view_watcher */ _)))));
262+
/* child_view_watcher */ _))),
263+
/*num_hit_regions*/ 0));
261264
}
262265

263266
fuchsia::ui::composition::OnNextFrameBeginValues WithPresentCredits(
@@ -466,7 +469,7 @@ TEST_F(FlatlandExternalViewEmbedderTest, SimpleScene) {
466469
fake_flatland().graph(),
467470
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token, view_ref,
468471
/*layers*/
469-
{IsImageLayer(frame_size, kFirstLayerBlendMode)}));
472+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1)}));
470473
}
471474

472475
TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
@@ -555,9 +558,9 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
555558
fake_flatland().graph(),
556559
IsFlutterGraph(
557560
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
558-
{IsImageLayer(frame_size, kFirstLayerBlendMode),
561+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
559562
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
560-
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
563+
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
561564

562565
// Destroy the view. The scene graph shouldn't change yet.
563566
external_view_embedder.DestroyView(
@@ -566,9 +569,9 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
566569
fake_flatland().graph(),
567570
IsFlutterGraph(
568571
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
569-
{IsImageLayer(frame_size, kFirstLayerBlendMode),
572+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
570573
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
571-
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
574+
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
572575

573576
// Draw another frame without the view. The scene graph shouldn't change yet.
574577
DrawSimpleFrame(
@@ -587,16 +590,135 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
587590
fake_flatland().graph(),
588591
IsFlutterGraph(
589592
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
590-
{IsImageLayer(frame_size, kFirstLayerBlendMode),
593+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
591594
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
592-
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
595+
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
593596

594597
// Pump the message loop. The scene updates should propagate to flatland.
595598
loop().RunUntilIdle();
599+
EXPECT_THAT(
600+
fake_flatland().graph(),
601+
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
602+
view_ref, /*layers*/
603+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1)}));
604+
}
605+
606+
TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView_NoOverlay) {
607+
fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
608+
fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
609+
fuchsia::ui::views::ViewCreationToken view_creation_token;
610+
fuchsia::ui::views::ViewRef view_ref;
611+
auto view_creation_token_status = zx::channel::create(
612+
0u, &viewport_creation_token.value, &view_creation_token.value);
613+
ASSERT_EQ(view_creation_token_status, ZX_OK);
614+
auto view_ref_pair = scenic::ViewRefPair::New();
615+
view_ref_pair.view_ref.Clone(&view_ref);
616+
617+
// Create the `FlatlandExternalViewEmbedder` and pump the message loop until
618+
// the initial scene graph is setup.
619+
FlatlandExternalViewEmbedder external_view_embedder(
620+
std::move(view_creation_token),
621+
fuchsia::ui::views::ViewIdentityOnCreation{
622+
.view_ref = std::move(view_ref_pair.view_ref),
623+
.view_ref_control = std::move(view_ref_pair.control_ref),
624+
},
625+
fuchsia::ui::composition::ViewBoundProtocols{},
626+
parent_viewport_watcher.NewRequest(), flatland_connection(),
627+
fake_surface_producer());
628+
flatland_connection()->Present();
629+
loop().RunUntilIdle();
630+
fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
631+
loop().RunUntilIdle();
596632
EXPECT_THAT(fake_flatland().graph(),
597633
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
598-
view_ref, /*layers*/
599-
{IsImageLayer(frame_size, kFirstLayerBlendMode)}));
634+
view_ref));
635+
636+
// Create the view before drawing the scene.
637+
const SkSize child_view_size_signed = SkSize::Make(256.f, 512.f);
638+
const fuchsia::math::SizeU child_view_size{
639+
static_cast<uint32_t>(child_view_size_signed.width()),
640+
static_cast<uint32_t>(child_view_size_signed.height())};
641+
auto [child_view_token, child_viewport_token] = ViewTokenPair::New();
642+
const uint32_t child_view_id = child_viewport_token.value.get();
643+
flutter::EmbeddedViewParams child_view_params(
644+
SkMatrix::I(), child_view_size_signed, flutter::MutatorsStack());
645+
external_view_embedder.CreateView(
646+
child_view_id, []() {},
647+
[](fuchsia::ui::composition::ContentId,
648+
fuchsia::ui::composition::ChildViewWatcherPtr) {});
649+
650+
// Draw the scene. The scene graph shouldn't change yet.
651+
const SkISize frame_size_signed = SkISize::Make(512, 512);
652+
const fuchsia::math::SizeU frame_size{
653+
static_cast<uint32_t>(frame_size_signed.width()),
654+
static_cast<uint32_t>(frame_size_signed.height())};
655+
DrawFrameWithView(
656+
external_view_embedder, frame_size_signed, 1.f, child_view_id,
657+
child_view_params,
658+
[](SkCanvas* canvas) {
659+
const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
660+
canvas->imageInfo().height());
661+
SkPaint rect_paint;
662+
rect_paint.setColor(SK_ColorGREEN);
663+
canvas->translate(canvas_size.width() / 4.f,
664+
canvas_size.height() / 2.f);
665+
canvas->drawRect(SkRect::MakeWH(canvas_size.width() / 32.f,
666+
canvas_size.height() / 32.f),
667+
rect_paint);
668+
},
669+
[](SkCanvas* canvas) {});
670+
EXPECT_THAT(fake_flatland().graph(),
671+
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
672+
view_ref));
673+
674+
// Pump the message loop. The scene updates should propagate to flatland.
675+
loop().RunUntilIdle();
676+
fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
677+
loop().RunUntilIdle();
678+
EXPECT_THAT(
679+
fake_flatland().graph(),
680+
IsFlutterGraph(
681+
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
682+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
683+
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
684+
685+
// Destroy the view. The scene graph shouldn't change yet.
686+
external_view_embedder.DestroyView(
687+
child_view_id, [](fuchsia::ui::composition::ContentId) {});
688+
EXPECT_THAT(
689+
fake_flatland().graph(),
690+
IsFlutterGraph(
691+
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
692+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
693+
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
694+
695+
// Draw another frame without the view. The scene graph shouldn't change yet.
696+
DrawSimpleFrame(
697+
external_view_embedder, frame_size_signed, 1.f, [](SkCanvas* canvas) {
698+
const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
699+
canvas->imageInfo().height());
700+
SkPaint rect_paint;
701+
rect_paint.setColor(SK_ColorGREEN);
702+
canvas->translate(canvas_size.width() / 4.f,
703+
canvas_size.height() / 2.f);
704+
canvas->drawRect(SkRect::MakeWH(canvas_size.width() / 32.f,
705+
canvas_size.height() / 32.f),
706+
rect_paint);
707+
});
708+
EXPECT_THAT(
709+
fake_flatland().graph(),
710+
IsFlutterGraph(
711+
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
712+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
713+
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
714+
715+
// Pump the message loop. The scene updates should propagate to flatland.
716+
loop().RunUntilIdle();
717+
EXPECT_THAT(
718+
fake_flatland().graph(),
719+
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
720+
view_ref, /*layers*/
721+
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1)}));
600722
}
601723

602724
} // namespace flutter_runner::testing

0 commit comments

Comments
 (0)