Flutter Engine
The Flutter Engine
fake_flatland.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "fake_flatland.h"
6
7#include <zircon/types.h>
8
9#include <algorithm> // For std::remove_if
10#include <memory>
11
12#include "flutter/fml/logging.h"
13
15
17 : allocator_binding_(this),
18 flatland_binding_(this),
19 present_handler_([](auto args) {}) {}
20
22
23fuchsia::ui::composition::AllocatorHandle FakeFlatland::ConnectAllocator(
24 async_dispatcher_t* dispatcher) {
25 FML_CHECK(!allocator_binding_.is_bound());
26
27 fuchsia::ui::composition::AllocatorHandle allocator;
28 allocator_binding_.Bind(allocator.NewRequest(), dispatcher);
29
30 return allocator;
31}
32
33fuchsia::ui::composition::FlatlandHandle FakeFlatland::ConnectFlatland(
34 async_dispatcher_t* dispatcher) {
35 FML_CHECK(!flatland_binding_.is_bound());
36
37 fuchsia::ui::composition::FlatlandHandle flatland;
38 flatland_binding_.Bind(flatland.NewRequest(), dispatcher);
39
40 return flatland;
41}
42
43void FakeFlatland::Disconnect(fuchsia::ui::composition::FlatlandError error) {
44 flatland_binding_.events().OnError(error);
45 flatland_binding_.Unbind();
46 allocator_binding_
47 .Unbind(); // TODO(fxb/85619): Does the real Scenic unbind this when
48 // Flatland has an error? Or is it independent?
49}
50
52 present_handler_ =
53 present_handler ? std::move(present_handler) : [](auto args) {};
54}
55
57 fuchsia::ui::composition::OnNextFrameBeginValues
58 on_next_frame_begin_values) {
59 flatland_binding_.events().OnNextFrameBegin(
60 std::move(on_next_frame_begin_values));
61}
62
64 fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info) {
65 flatland_binding_.events().OnFramePresented(std::move(frame_presented_info));
66}
67
68void FakeFlatland::NotImplemented_(const std::string& name) {
69 FML_LOG(FATAL) << "FakeFlatland does not implement " << name;
70}
71
72void FakeFlatland::RegisterBufferCollection(
73 fuchsia::ui::composition::RegisterBufferCollectionArgs args,
74 RegisterBufferCollectionCallback callback) {
75 auto [export_token_koid, _] = GetKoids(args.export_token());
76 auto [__, emplace_binding_success] =
77 graph_bindings_.buffer_collections.emplace(
78 export_token_koid,
79 BufferCollectionBinding{
80 .export_token = std::move(*args.mutable_export_token()),
81 .sysmem_token =
82 std::move(*args.mutable_buffer_collection_token()),
83 .usage = args.usage(),
84 });
85 // TODO(fxb/85619): Disconnect the Allocator here
86 FML_CHECK(emplace_binding_success)
87 << "FakeFlatland::RegisterBufferCollection: BufferCollection already "
88 "exists with koid "
89 << export_token_koid;
90}
91
92void FakeFlatland::Present(fuchsia::ui::composition::PresentArgs args) {
93 // Each FIDL call between this `Present()` and the last one mutated the
94 // `pending_graph_` independently of the `current_graph_`. Only the
95 // `current_graph_` is visible externally in the test.
96 //
97 // `Present()` updates the current graph with a deep clone of the pending one.
98 current_graph_ = pending_graph_.Clone();
99
100 present_handler_(std::move(args));
101}
102
103void FakeFlatland::CreateView(
104 fuchsia::ui::views::ViewCreationToken token,
105 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
106 parent_viewport_watcher) {
107 CreateView2(std::move(token), fuchsia::ui::views::ViewIdentityOnCreation{},
108 fuchsia::ui::composition::ViewBoundProtocols{},
109 std::move(parent_viewport_watcher));
110}
111
112void FakeFlatland::CreateView2(
113 fuchsia::ui::views::ViewCreationToken token,
114 fuchsia::ui::views::ViewIdentityOnCreation view_identity,
115 fuchsia::ui::composition::ViewBoundProtocols view_protocols,
116 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
117 parent_viewport_watcher) {
118 // TODO(fxb/85619): Handle a 2nd CreateView call
119 FML_CHECK(!pending_graph_.view.has_value());
120 FML_CHECK(!graph_bindings_.viewport_watcher.has_value());
121
122 auto view_token_koids = GetKoids(token);
123 auto view_ref_koids = GetKoids(view_identity.view_ref);
124 auto view_ref_control_koids = GetKoids(view_identity.view_ref_control);
125 FML_CHECK(view_ref_koids.first == view_ref_control_koids.second);
126 FML_CHECK(view_ref_koids.second == view_ref_control_koids.first);
127
128 pending_graph_.view.emplace(FakeView{
129 .view_token = view_token_koids.first,
130 .view_ref = view_ref_koids.first,
131 .view_ref_control = view_ref_control_koids.first,
132 .view_ref_focused =
133 view_protocols.has_view_ref_focused()
134 ? GetKoids(view_protocols.view_ref_focused()).first
135 : zx_koid_t{},
136 .focuser = view_protocols.has_view_focuser()
137 ? GetKoids(view_protocols.view_focuser()).first
138 : zx_koid_t{},
139 .touch_source = view_protocols.has_touch_source()
140 ? GetKoids(view_protocols.touch_source()).first
141 : zx_koid_t{},
142 .mouse_source = view_protocols.has_mouse_source()
143 ? GetKoids(view_protocols.mouse_source()).first
144 : zx_koid_t{},
145 .parent_viewport_watcher = GetKoids(parent_viewport_watcher).first,
146 });
147 graph_bindings_.viewport_watcher.emplace(
148 view_token_koids.first,
149 ParentViewportWatcher(
150 std::move(token), std::move(view_identity), std::move(view_protocols),
151 std::move(parent_viewport_watcher), flatland_binding_.dispatcher()));
152}
153
154void FakeFlatland::CreateTransform(
155 fuchsia::ui::composition::TransformId transform_id) {
156 if (transform_id.value == 0) {
157 // TODO(fxb/85619): Raise a FlatlandError here
158 FML_CHECK(false)
159 << "FakeFlatland::CreateTransform: TransformId 0 is invalid.";
160 return;
161 }
162 if (pending_graph_.transform_map.count(transform_id.value) != 0) {
163 // TODO(fxb/85619): Raise a FlatlandError here
164 FML_CHECK(false) << "FakeFlatland::CreateTransform: TransformId "
165 << transform_id.value << " is already in use.";
166 return;
167 }
168
169 auto [emplaced_transform, emplace_success] =
170 pending_graph_.transform_map.emplace(
171 transform_id.value, std::make_shared<FakeTransform>(FakeTransform{
172 .id = transform_id,
173 }));
174 // TODO(fxb/85619): Raise a FlatlandError here
175 FML_CHECK(emplace_success)
176 << "FakeFlatland::CreateTransform: Internal error (transform_map) adding "
177 "transform with id: "
178 << transform_id.value;
179
180 auto [_, emplace_parent_success] = parents_map_.emplace(
181 transform_id.value,
182 std::make_pair(std::weak_ptr<FakeTransform>(),
183 std::weak_ptr(emplaced_transform->second)));
184 // TODO(fxb/85619): Raise a FlatlandError here
185 FML_CHECK(emplace_parent_success)
186 << "FakeFlatland::CreateTransform: Internal error (parent_map) adding "
187 "transform with id: "
188 << transform_id.value;
189}
190
191void FakeFlatland::SetTranslation(
192 fuchsia::ui::composition::TransformId transform_id,
193 fuchsia::math::Vec translation) {
194 if (transform_id.value == 0) {
195 // TODO(fxb/85619): Raise a FlatlandError here
196 FML_CHECK(false)
197 << "FakeFlatland::SetTranslation: TransformId 0 is invalid.";
198 return;
199 }
200
201 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
202 if (found_transform == pending_graph_.transform_map.end()) {
203 // TODO(fxb/85619): Raise a FlatlandError here
204 FML_CHECK(false) << "FakeFlatland::SetTranslation: TransformId "
205 << transform_id.value << " does not exist.";
206 return;
207 }
208
209 auto& transform = found_transform->second;
211 transform->translation = translation;
212}
213
214void FakeFlatland::SetScale(fuchsia::ui::composition::TransformId transform_id,
215 fuchsia::math::VecF scale) {
216 if (transform_id.value == 0) {
217 // TODO(fxb/85619): Raise a FlatlandError here
218 FML_CHECK(false) << "FakeFlatland::SetScale: TransformId 0 is invalid.";
219 return;
220 }
221
222 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
223 if (found_transform == pending_graph_.transform_map.end()) {
224 // TODO(fxb/85619): Raise a FlatlandError here
225 FML_CHECK(false) << "FakeFlatland::SetScale: TransformId "
226 << transform_id.value << " does not exist.";
227 return;
228 }
229
230 if (scale.x == 0.f || scale.y == 0.f) {
231 FML_CHECK(false) << "SetScale failed, zero values not allowed (" << scale.x
232 << ", " << scale.y << " ).";
233 return;
234 }
235
236 if (isinf(scale.x) || isinf(scale.y) || isnan(scale.x) || isnan(scale.y)) {
237 FML_CHECK(false) << "SetScale failed, invalid scale values (" << scale.x
238 << ", " << scale.y << " ).";
239 return;
240 }
241
242 auto& transform = found_transform->second;
244 transform->scale = scale;
245}
246
247void FakeFlatland::SetOrientation(
248 fuchsia::ui::composition::TransformId transform_id,
249 fuchsia::ui::composition::Orientation orientation) {
250 if (transform_id.value == 0) {
251 // TODO(fxb/85619): Raise a FlatlandError here
252 FML_CHECK(false)
253 << "FakeFlatland::SetOrientation: TransformId 0 is invalid.";
254 return;
255 }
256
257 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
258 if (found_transform == pending_graph_.transform_map.end()) {
259 // TODO(fxb/85619): Raise a FlatlandError here
260 FML_CHECK(false) << "FakeFlatland::SetOrientation: TransformId "
261 << transform_id.value << " does not exist.";
262 return;
263 }
264
265 auto& transform = found_transform->second;
267 transform->orientation = orientation;
268}
269
270void FakeFlatland::SetOpacity(
271 fuchsia::ui::composition::TransformId transform_id,
272 float value) {
273 if (transform_id.value == 0) {
274 // TODO(fxb/85619): Raise a FlatlandError here
275 FML_CHECK(false) << "FakeFlatland::SetOpacity: TransformId 0 is invalid.";
276 return;
277 }
278
279 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
280 if (found_transform == pending_graph_.transform_map.end()) {
281 // TODO(fxb/85619): Raise a FlatlandError here
282 FML_CHECK(false) << "FakeFlatland::SetOpacity: TransformId "
283 << transform_id.value << " does not exist.";
284 return;
285 }
286
287 if (value < 0.f || value > 1.f) {
288 FML_CHECK(false) << "FakeFlatland::SetOpacity: Invalid opacity value.";
289 }
290
291 auto& transform = found_transform->second;
293 transform->opacity = value;
294}
295
296void FakeFlatland::SetClipBoundary(
297 fuchsia::ui::composition::TransformId transform_id,
298 std::unique_ptr<fuchsia::math::Rect> bounds) {
299 if (transform_id.value == 0) {
300 // TODO(fxb/85619): Raise a FlatlandError here
301 FML_CHECK(false)
302 << "FakeFlatland::SetClipBoundary: TransformId 0 is invalid.";
303 return;
304 }
305
306 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
307 if (found_transform == pending_graph_.transform_map.end()) {
308 // TODO(fxb/85619): Raise a FlatlandError here
309 FML_CHECK(false) << "FakeFlatland::SetClipBoundary: TransformId "
310 << transform_id.value << " does not exist.";
311 return;
312 }
313
314 auto& transform = found_transform->second;
316 if (bounds == nullptr) {
317 transform->clip_bounds = std::nullopt;
318 return;
319 }
320
321 transform->clip_bounds = *bounds.get();
322}
323
324// TODO(fxbug.dev/89111): Re-enable once SDK rolls.
325// void FakeFlatland::SetImageOpacity(
326// fuchsia::ui::composition::ContentId content_id,
327// float opacity) {
328// if (content_id.value == 0) {
329// // TODO(fxb/85619): Raise a FlatlandError here
330// FML_CHECK(false)
331// << "FakeFlatland::SetImageOpacity: ContentId 0 is invalid.";
332// return;
333// }
334
335// auto found_content = pending_graph_.content_map.find(image_id.value);
336// if (found_content == pending_graph_.content_map.end()) {
337// // TODO(fxb/85619): Raise a FlatlandError here
338// FML_CHECK(false) << "FakeFlatland::SetImageOpacity: ContentId "
339// << image_id.value << " does not exist.";
340// return;
341// }
342
343// auto& content = found_content->second;
344// FML_CHECK(content);
345// FakeImage* image = std::get_if<FakeImage>(content.get());
346// if (image == nullptr) {
347// // TODO(fxb/85619): Raise a FlatlandError here
348// FML_CHECK(false) << "FakeFlatland::SetImageOpacity: ContentId "
349// << image_id.value << " is not an Image.";
350// return;
351// }
352
353// image->opacity = opacity;
354// }
355
356void FakeFlatland::AddChild(
357 fuchsia::ui::composition::TransformId parent_transform_id,
358 fuchsia::ui::composition::TransformId child_transform_id) {
359 if (parent_transform_id.value == 0) {
360 // TODO(fxb/85619): Raise a FlatlandError here
361 FML_CHECK(false)
362 << "FakeFlatland::AddChild: Parent TransformId 0 is invalid.";
363 return;
364 }
365 if (child_transform_id.value == 0) {
366 // TODO(fxb/85619): Raise a FlatlandError here
367 FML_CHECK(false)
368 << "FakeFlatland::AddChild: Child TransformId 0 is invalid.";
369 return;
370 }
371
372 auto found_parent =
373 pending_graph_.transform_map.find(parent_transform_id.value);
374 if (found_parent == pending_graph_.transform_map.end()) {
375 // TODO(fxb/85619): Raise a FlatlandError here
376 FML_CHECK(false) << "FakeFlatland::AddChild: Parent TransformId "
377 << parent_transform_id.value << " does not exist.";
378 return;
379 }
380 auto found_child =
381 pending_graph_.transform_map.find(child_transform_id.value);
382 if (found_child == pending_graph_.transform_map.end()) {
383 // TODO(fxb/85619): Raise a FlatlandError here
384 FML_CHECK(false) << "FakeFlatland::AddChild: Child TransformId "
385 << child_transform_id.value << " does not exist.";
386 return;
387 }
388 auto found_child_old_parent = parents_map_.find(child_transform_id.value);
389 if (found_child_old_parent == parents_map_.end()) {
390 // TODO(fxb/85619): Raise a FlatlandError here
391 FML_CHECK(false)
392 << "FakeFlatland::AddChild: Internal error - Child TransformId "
393 << child_transform_id.value << " is not in parents_map.";
394 return;
395 }
396 if (found_child_old_parent->second.second.expired()) {
397 // TODO(fxb/85619): Raise a FlatlandError here
398 FML_CHECK(false)
399 << "FakeFlatland::AddChild: Internal error - Child TransformId "
400 << child_transform_id.value << " is expired in parents_map.";
401 return;
402 }
403
404 auto& child = found_child->second;
405 auto& new_parent = found_parent->second;
406 new_parent->children.push_back(child);
407 if (auto old_parent = found_child_old_parent->second.first.lock()) {
408 old_parent->children.erase(std::remove_if(
409 old_parent->children.begin(), old_parent->children.end(),
410 [&child](const auto& transform) { return transform == child; }));
411 }
412 found_child_old_parent->second.first = std::weak_ptr(new_parent);
413}
414
415void FakeFlatland::RemoveChild(
416 fuchsia::ui::composition::TransformId parent_transform_id,
417 fuchsia::ui::composition::TransformId child_transform_id) {
418 if (parent_transform_id.value == 0) {
419 // TODO(fxb/85619): Raise a FlatlandError here
420 FML_CHECK(false)
421 << "FakeFlatland::RemoveChild: Parent TransformId 0 is invalid.";
422 return;
423 }
424 if (child_transform_id.value == 0) {
425 // TODO(fxb/85619): Raise a FlatlandError here
426 FML_CHECK(false)
427 << "FakeFlatland::RemoveChild: Child TransformId 0 is invalid.";
428 return;
429 }
430
431 auto found_child =
432 pending_graph_.transform_map.find(child_transform_id.value);
433 if (found_child == pending_graph_.transform_map.end()) {
434 // TODO(fxb/85619): Raise a FlatlandError here
435 FML_CHECK(false) << "FakeFlatland::RemoveChild: Child TransformId "
436 << child_transform_id.value << " does not exist.";
437 return;
438 }
439
440 auto found_parent =
441 pending_graph_.transform_map.find(parent_transform_id.value);
442 if (found_parent == pending_graph_.transform_map.end()) {
443 // TODO(fxb/85619): Raise a FlatlandError here
444 FML_CHECK(false) << "FakeFlatland::RemoveChild: Parent TransformId "
445 << parent_transform_id.value << " does not exist.";
446 return;
447 }
448
449 auto found_child_parent = parents_map_.find(child_transform_id.value);
450 if (found_child_parent == parents_map_.end()) {
451 // TODO(fxb/85619): Raise a FlatlandError here
452 FML_CHECK(false)
453 << "FakeFlatland::RemoveChild: Internal error - Child TransformId "
454 << child_transform_id.value << " is not in parents_map.";
455 return;
456 }
457 if (found_child_parent->second.second.expired()) {
458 // TODO(fxb/85619): Raise a FlatlandError here
459 FML_CHECK(false)
460 << "FakeFlatland::RemoveChild: Internal error - Child TransformId "
461 << child_transform_id.value << " is expired in parents_map.";
462 return;
463 }
464 if (found_child_parent->second.first.lock() != found_parent->second) {
465 // TODO(fxb/85619): Raise a FlatlandError here
466 FML_CHECK(false)
467 << "FakeFlatland::RemoveChild: Internal error - Child TransformId "
468 << child_transform_id.value << " is not a child of Parent TransformId "
469 << parent_transform_id.value << ".";
470 return;
471 }
472
473 found_child_parent->second.first = std::weak_ptr<FakeTransform>();
474 found_parent->second->children.erase(std::remove_if(
475 found_parent->second->children.begin(),
476 found_parent->second->children.end(),
477 [child_to_remove = found_child->second](const auto& child) {
478 return child == child_to_remove;
479 }));
480}
481
482void FakeFlatland::SetContent(
483 fuchsia::ui::composition::TransformId transform_id,
484 fuchsia::ui::composition::ContentId content_id) {
485 if (transform_id.value == 0) {
486 // TODO(fxb/85619): Raise a FlatlandError here
487 FML_CHECK(false) << "FakeFlatland::SetContent: TransformId 0 is invalid.";
488 return;
489 }
490
491 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
492 if (found_transform == pending_graph_.transform_map.end()) {
493 // TODO(fxb/85619): Raise a FlatlandError here
494 FML_CHECK(false) << "FakeFlatland::SetContent: TransformId "
495 << transform_id.value << " does not exist.";
496 return;
497 }
498
499 auto& transform = found_transform->second;
501 if (content_id.value == 0) {
502 transform->content.reset();
503 return;
504 }
505
506 auto found_content = pending_graph_.content_map.find(content_id.value);
507 if (found_content == pending_graph_.content_map.end()) {
508 // TODO(fxb/85619): Raise a FlatlandError here
509 FML_CHECK(false) << "FakeFlatland::SetContent: ContentId "
510 << content_id.value << " does not exist.";
511 return;
512 }
513
514 auto& content = found_content->second;
516 transform->content = content;
517}
518
519void FakeFlatland::SetRootTransform(
520 fuchsia::ui::composition::TransformId transform_id) {
521 if (transform_id.value == 0) {
522 // TODO(fxb/85619): Raise a FlatlandError here
523 FML_CHECK(false)
524 << "FakeFlatland::SetRootTransform: TransformId 0 is invalid.";
525 return;
526 }
527
528 auto found_new_root = pending_graph_.transform_map.find(transform_id.value);
529 if (found_new_root == pending_graph_.transform_map.end()) {
530 // TODO(fxb/85619): Raise a FlatlandError here
531 FML_CHECK(false) << "FakeFlatland::SetRootTransform: TransformId "
532 << transform_id.value << " does not exist.";
533 return;
534 }
535
536 pending_graph_.root_transform = found_new_root->second;
537}
538
539void FakeFlatland::CreateViewport(
540 fuchsia::ui::composition::ContentId viewport_id,
541 fuchsia::ui::views::ViewportCreationToken token,
542 fuchsia::ui::composition::ViewportProperties properties,
543 fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
544 child_view_watcher) {
545 if (viewport_id.value == 0) {
546 // TODO(fxb/85619): Raise a FlatlandError here
547 FML_CHECK(false) << "FakeFlatland::CreateViewport: ContentId 0 is invalid.";
548 return;
549 }
550 if (pending_graph_.content_map.count(viewport_id.value) != 0) {
551 // TODO(fxb/85619): Raise a FlatlandError here
552 FML_CHECK(false) << "FakeFlatland::CreateViewport: ContentId "
553 << viewport_id.value << " is already in use.";
554 return;
555 }
556
557 auto viewport_token_koids = GetKoids(token.value);
558 auto [emplaced_viewport, emplace_success] =
559 pending_graph_.content_map.emplace(
560 viewport_id.value,
561 std::make_shared<FakeContent>(FakeViewport{
562 .id = viewport_id,
563 .viewport_properties = std::move(properties),
564 .viewport_token = viewport_token_koids.first,
565 .child_view_watcher = GetKoids(child_view_watcher).first,
566 }));
567 // TODO(fxb/85619): Raise a FlatlandError here
568 FML_CHECK(emplace_success)
569 << "FakeFlatland::CreateViewport: Internal error (content_map) adding "
570 "viewport with id: "
571 << viewport_id.value;
572
573 auto [_, emplace_binding_success] = graph_bindings_.view_watchers.emplace(
574 viewport_token_koids.first,
575 ChildViewWatcher(std::move(token), std::move(child_view_watcher),
576 flatland_binding_.dispatcher()));
577 // TODO(fxb/85619): Raise a FlatlandError here
578 FML_CHECK(emplace_binding_success)
579 << "FakeFlatland::CreateViewport: Internal error (view_watcher) adding "
580 "viewport with id: "
581 << viewport_id.value;
582}
583
584void FakeFlatland::CreateImage(
585 fuchsia::ui::composition::ContentId image_id,
586 fuchsia::ui::composition::BufferCollectionImportToken import_token,
587 uint32_t vmo_index,
588 fuchsia::ui::composition::ImageProperties properties) {
589 if (image_id.value == 0) {
590 // TODO(fxb/85619): Raise a FlatlandError here
591 FML_CHECK(false) << "FakeFlatland::CreateImage: ContentId 0 is invalid.";
592 return;
593 }
594 if (pending_graph_.content_map.count(image_id.value) != 0) {
595 // TODO(fxb/85619): Raise a FlatlandError here
596 FML_CHECK(false) << "FakeFlatland::CreateImage: ContentId "
597 << image_id.value << " is already in use.";
598 return;
599 }
600
601 auto import_token_koids = GetKoids(import_token);
602 auto [emplaced_image, emplace_success] = pending_graph_.content_map.emplace(
603 image_id.value, std::make_shared<FakeContent>(FakeImage{
604 .id = image_id,
605 .image_properties = std::move(properties),
606 .import_token = import_token_koids.first,
607 .vmo_index = vmo_index,
608 }));
609 // TODO(fxb/85619): Raise a FlatlandError here
610 FML_CHECK(emplace_success)
611 << "FakeFlatland::CreateImage: Internal error (content_map) adding "
612 "image with id: "
613 << image_id.value;
614
615 auto [_, emplace_binding_success] = graph_bindings_.images.emplace(
616 import_token_koids.first, ImageBinding{
617 .import_token = std::move(import_token),
618 });
619 // TODO(fxb/85619): Raise a FlatlandError here
620 FML_CHECK(emplace_binding_success)
621 << "FakeFlatland::CreateImage: Internal error (images_binding) adding "
622 "viewport with id: "
623 << image_id.value;
624}
625
626void FakeFlatland::SetImageSampleRegion(
627 fuchsia::ui::composition::ContentId image_id,
628 fuchsia::math::RectF rect) {
629 if (image_id.value == 0) {
630 // TODO(fxb/85619): Raise a FlatlandError here
631 FML_CHECK(false)
632 << "FakeFlatland::SetImageSampleRegion: ContentId 0 is invalid.";
633 return;
634 }
635
636 auto found_content = pending_graph_.content_map.find(image_id.value);
637 if (found_content == pending_graph_.content_map.end()) {
638 // TODO(fxb/85619): Raise a FlatlandError here
639 FML_CHECK(false) << "FakeFlatland::SetImageSampleRegion: ContentId "
640 << image_id.value << " does not exist.";
641 return;
642 }
643
644 auto& content = found_content->second;
646 FakeImage* image = std::get_if<FakeImage>(content.get());
647 if (image == nullptr) {
648 // TODO(fxb/85619): Raise a FlatlandError here
649 FML_CHECK(false) << "FakeFlatland::SetImageSampleRegion: ContentId "
650 << image_id.value << " is not an Image.";
651 return;
652 }
653
654 image->sample_region = rect;
655}
656
657void FakeFlatland::SetImageDestinationSize(
658 fuchsia::ui::composition::ContentId image_id,
659 fuchsia::math::SizeU size) {
660 if (image_id.value == 0) {
661 // TODO(fxb/85619): Raise a FlatlandError here
662 FML_CHECK(false)
663 << "FakeFlatland::SetImageDestinationSize: ContentId 0 is invalid.";
664 return;
665 }
666
667 auto found_content = pending_graph_.content_map.find(image_id.value);
668 if (found_content == pending_graph_.content_map.end()) {
669 // TODO(fxb/85619): Raise a FlatlandError here
670 FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
671 << image_id.value << " does not exist.";
672 return;
673 }
674
675 auto& content = found_content->second;
677 FakeImage* image = std::get_if<FakeImage>(content.get());
678 if (image == nullptr) {
679 // TODO(fxb/85619): Raise a FlatlandError here
680 FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
681 << image_id.value << " is not an Image.";
682 return;
683 }
684
685 image->destination_size = size;
686}
687
688void FakeFlatland::SetImageBlendingFunction(
689 fuchsia::ui::composition::ContentId image_id,
691 if (image_id.value == 0) {
692 // TODO(fxb/85619): Raise a FlatlandError here
693 FML_CHECK(false)
694 << "FakeFlatland::SetImageDestinationSize: ContentId 0 is invalid.";
695 return;
696 }
697
698 auto found_content = pending_graph_.content_map.find(image_id.value);
699 if (found_content == pending_graph_.content_map.end()) {
700 // TODO(fxb/85619): Raise a FlatlandError here
701 FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
702 << image_id.value << " does not exist.";
703 return;
704 }
705
706 auto& content = found_content->second;
708 FakeImage* image = std::get_if<FakeImage>(content.get());
709 if (image == nullptr) {
710 // TODO(fxb/85619): Raise a FlatlandError here
711 FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
712 << image_id.value << " is not an Image.";
713 return;
714 }
715
716 image->blend_mode = blend_mode;
717}
718
719void FakeFlatland::SetViewportProperties(
720 fuchsia::ui::composition::ContentId viewport_id,
721 fuchsia::ui::composition::ViewportProperties properties) {
722 if (viewport_id.value == 0) {
723 // TODO(fxb/85619): Raise a FlatlandError here
724 FML_CHECK(false)
725 << "FakeFlatland::SetViewportProperties: ContentId 0 is invalid.";
726 return;
727 }
728
729 auto found_content = pending_graph_.content_map.find(viewport_id.value);
730 if (found_content == pending_graph_.content_map.end()) {
731 // TODO(fxb/85619): Raise a FlatlandError here
732 FML_CHECK(false) << "FakeFlatland::SetViewportProperties: ContentId "
733 << viewport_id.value << " does not exist.";
734 return;
735 }
736
737 auto& content = found_content->second;
739 FakeViewport* viewport = std::get_if<FakeViewport>(content.get());
740 if (viewport == nullptr) {
741 // TODO(fxb/85619): Raise a FlatlandError here
742 FML_CHECK(false) << "FakeFlatland::SetViewportProperties: ContentId "
743 << viewport_id.value << " is not a Viewport.";
744 return;
745 }
746
747 viewport->viewport_properties = std::move(properties);
748}
749
750void FakeFlatland::ReleaseTransform(
751 fuchsia::ui::composition::TransformId transform_id) {
752 if (transform_id.value == 0) {
753 // TODO(fxb/85619): Raise a FlatlandError here
754 FML_CHECK(false)
755 << "FakeFlatland::ReleaseTransform: TransformId 0 is invalid.";
756 return;
757 }
758
759 size_t erased = pending_graph_.transform_map.erase(transform_id.value);
760 if (erased == 0) {
761 // TODO(fxb/85619): Raise a FlatlandError here
762 FML_CHECK(false) << "FakeFlatland::ReleaseTransform: TransformId "
763 << transform_id.value << " does not exist.";
764 }
765
766 size_t parents_erased = parents_map_.erase(transform_id.value);
767 if (parents_erased == 0) {
768 // TODO(fxb/85619): Raise a FlatlandError here
769 FML_CHECK(false) << "FakeFlatland::ReleaseTransform: TransformId "
770 << transform_id.value << " does not exist in parents_map.";
771 }
772}
773
774void FakeFlatland::ReleaseViewport(
775 fuchsia::ui::composition::ContentId viewport_id,
776 ReleaseViewportCallback callback) {
777 if (viewport_id.value == 0) {
778 // TODO(fxb/85619): Raise a FlatlandError here
779 FML_CHECK(false)
780 << "FakeFlatland::ReleaseViewport: ContentId 0 is invalid.";
781 return;
782 }
783
784 auto found_content = pending_graph_.content_map.find(viewport_id.value);
785 if (found_content == pending_graph_.content_map.end()) {
786 // TODO(fxb/85619): Raise a FlatlandError here
787 FML_CHECK(false) << "FakeFlatland::ReleaseViewport: ContentId "
788 << viewport_id.value << " does not exist.";
789 return;
790 }
791
792 auto& content = found_content->second;
794 FakeViewport* viewport = std::get_if<FakeViewport>(content.get());
795 if (viewport == nullptr) {
796 // TODO(fxb/85619): Raise a FlatlandError here
797 FML_CHECK(false) << "FakeFlatland::ReleaseViewport: ContentId "
798 << viewport_id.value << " is not a Viewport.";
799 return;
800 }
801
802 pending_graph_.content_map.erase(found_content);
803}
804
805void FakeFlatland::ReleaseImage(fuchsia::ui::composition::ContentId image_id) {
806 if (image_id.value == 0) {
807 // TODO(fxb/85619): Raise a FlatlandError here
808 FML_CHECK(false) << "FakeFlatland::ReleaseImage: ContentId 0 is invalid.";
809 return;
810 }
811
812 auto found_content = pending_graph_.content_map.find(image_id.value);
813 if (found_content == pending_graph_.content_map.end()) {
814 // TODO(fxb/85619): Raise a FlatlandError here
815 FML_CHECK(false) << "FakeFlatland::ReleaseImage: ContentId "
816 << image_id.value << " does not exist.";
817 return;
818 }
819
820 auto& content = found_content->second;
822 FakeImage* image = std::get_if<FakeImage>(content.get());
823 if (image == nullptr) {
824 // TODO(fxb/85619): Raise a FlatlandError here
825 FML_CHECK(false) << "FakeFlatland::ReleaseImage: ContentId "
826 << image_id.value << " is not a Viewport.";
827 return;
828 }
829
830 pending_graph_.content_map.erase(found_content);
831}
832
833void FakeFlatland::SetHitRegions(
834 fuchsia::ui::composition::TransformId transform_id,
835 std::vector<fuchsia::ui::composition::HitRegion> regions) {
836 if (transform_id.value == 0) {
837 // TODO(fxb/85619): Raise a FlatlandError here
838 FML_CHECK(false)
839 << "FakeFlatland::SetTranslation: TransformId 0 is invalid.";
840 return;
841 }
842
843 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
844 if (found_transform == pending_graph_.transform_map.end()) {
845 // TODO(fxb/85619): Raise a FlatlandError here
846 FML_CHECK(false) << "FakeFlatland::SetTranslation: TransformId "
847 << transform_id.value << " does not exist.";
848 return;
849 }
850
851 auto& transform = found_transform->second;
853 transform->hit_regions = std::move(regions);
854}
855
856void FakeFlatland::SetInfiniteHitRegion(
857 fuchsia::ui::composition::TransformId transform_id,
858 fuchsia::ui::composition::HitTestInteraction hit_test) {
859 if (transform_id.value == 0) {
860 // TODO(fxb/85619): Raise a FlatlandError here
861 FML_CHECK(false)
862 << "FakeFlatland::SetTranslation: TransformId 0 is invalid.";
863 return;
864 }
865
866 auto found_transform = pending_graph_.transform_map.find(transform_id.value);
867 if (found_transform == pending_graph_.transform_map.end()) {
868 // TODO(fxb/85619): Raise a FlatlandError here
869 FML_CHECK(false) << "FakeFlatland::SetTranslation: TransformId "
870 << transform_id.value << " does not exist.";
871 return;
872 }
873
874 auto& transform = found_transform->second;
875 ZX_ASSERT(transform);
876 transform->hit_regions = {kInfiniteHitRegion};
877}
878
879void FakeFlatland::Clear() {
880 parents_map_.clear();
881 pending_graph_.Clear();
882}
883
884void FakeFlatland::SetDebugName(std::string debug_name) {
885 debug_name_ = std::move(debug_name);
886}
887
888FakeFlatland::ParentViewportWatcher::ParentViewportWatcher(
889 fuchsia::ui::views::ViewCreationToken view_token,
890 fuchsia::ui::views::ViewIdentityOnCreation view_identity,
891 fuchsia::ui::composition::ViewBoundProtocols view_protocols,
892 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
893 parent_viewport_watcher,
894 async_dispatcher_t* dispatcher)
895 : view_token(std::move(view_token)),
896 view_identity(std::move(view_identity)),
897 view_protocols(std::move(view_protocols)),
898 parent_viewport_watcher(this,
899 std::move(parent_viewport_watcher),
900 dispatcher) {}
901
902FakeFlatland::ParentViewportWatcher::ParentViewportWatcher(
903 ParentViewportWatcher&& other)
904 : view_token(std::move(other.view_token)),
905 view_identity(std::move(other.view_identity)),
906 view_protocols(std::move(other.view_protocols)),
907 parent_viewport_watcher(this,
908 other.parent_viewport_watcher.Unbind(),
909 other.parent_viewport_watcher.dispatcher()) {}
910
911FakeFlatland::ParentViewportWatcher::~ParentViewportWatcher() = default;
912
913void FakeFlatland::ParentViewportWatcher::NotImplemented_(
914 const std::string& name) {
915 FML_LOG(FATAL) << "FakeFlatland::ParentViewportWatcher does not implement "
916 << name;
917}
918
919void FakeFlatland::ParentViewportWatcher::GetLayout(
920 GetLayoutCallback callback) {
921 NotImplemented_("GetLayout");
922}
923
924void FakeFlatland::ParentViewportWatcher::GetStatus(
925 GetStatusCallback callback) {
926 NotImplemented_("GetStatus");
927}
928
929FakeFlatland::ChildViewWatcher::ChildViewWatcher(
930 fuchsia::ui::views::ViewportCreationToken viewport_token,
931 fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
932 child_view_watcher,
933 async_dispatcher_t* dispatcher)
934 : viewport_token(std::move(viewport_token)),
935 child_view_watcher(this, std::move(child_view_watcher), dispatcher) {}
936
937FakeFlatland::ChildViewWatcher::ChildViewWatcher(ChildViewWatcher&& other)
938 : viewport_token(std::move(other.viewport_token)),
939 child_view_watcher(this,
940 other.child_view_watcher.Unbind(),
941 other.child_view_watcher.dispatcher()) {}
942
943FakeFlatland::ChildViewWatcher::~ChildViewWatcher() = default;
944
945void FakeFlatland::ChildViewWatcher::NotImplemented_(const std::string& name) {
946 FML_LOG(FATAL) << "FakeFlatland::ChildViewWatcher does not implement "
947 << name;
948}
949
950void FakeFlatland::ChildViewWatcher::GetStatus(GetStatusCallback callback) {
951 NotImplemented_("GetStatus");
952}
953
954} // namespace flutter_runner::testing
#define __
fuchsia::ui::composition::FlatlandHandle ConnectFlatland(async_dispatcher_t *dispatcher=nullptr)
fuchsia::ui::composition::AllocatorHandle ConnectAllocator(async_dispatcher_t *dispatcher=nullptr)
std::function< void(fuchsia::ui::composition::PresentArgs)> PresentHandler
Definition: fake_flatland.h:72
void SetPresentHandler(PresentHandler present_handler)
void FireOnFramePresentedEvent(fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info)
const std::string & debug_name() const
Definition: fake_flatland.h:81
void FireOnNextFrameBeginEvent(fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values)
void Disconnect(fuchsia::ui::composition::FlatlandError error)
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_CHECK(condition)
Definition: logging.h:85
union flutter::testing::@2836::KeyboardChange::@76 content
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< const SkImage > image
Definition: SkRecords.h:269
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
std::pair< zx_koid_t, zx_koid_t > GetKoids(const ZX &kobj)
static constexpr fuchsia::ui::composition::HitRegion kInfiniteHitRegion
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
BlendMode
Definition: color.h:59
Definition: ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
const Scalar scale
std::unordered_map< ContentIdKey, std::shared_ptr< FakeContent > > content_map
std::shared_ptr< FakeTransform > root_transform
std::unordered_map< TransformIdKey, std::shared_ptr< FakeTransform > > transform_map