Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
fake_flatland.h
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#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_
6#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_
7
8#include <fuchsia/math/cpp/fidl.h>
9#include <fuchsia/scenic/scheduling/cpp/fidl.h>
10#include <fuchsia/sysmem/cpp/fidl.h>
11#include <fuchsia/ui/composition/cpp/fidl.h>
12#include <fuchsia/ui/composition/cpp/fidl_test_base.h>
13#include <fuchsia/ui/views/cpp/fidl.h>
14#include <lib/async/dispatcher.h>
15#include <lib/fidl/cpp/binding.h>
16#include <lib/fidl/cpp/interface_request.h>
17
18#include <cstdint>
19#include <functional>
20#include <string>
21#include <unordered_map>
22#include <vector>
23
24#include "flutter/fml/logging.h"
25#include "flutter/fml/macros.h"
26
27#include "fake_flatland_types.h"
28
30
31// A lightweight fake implementation of the Flatland API.
32//
33// The fake has no side effects besides mutating its own internal state
34// according to the rules of interacting with the Flatland API. It makes that
35// internal state available for inspection by a test.
36//
37// Thus it allows tests to do a few things that would be difficult using either
38// a mock implementation or the real implementation:
39// + It allows the user to hook `Present` invocations and respond with
40// stubbed-out `FuturePresentationTimes`, but more crucially it mimics the
41// real Flatland behavior of only processing commands when a `Present` is
42// invoked.
43// + It allows the user to inspect a snapshot of the scene graph at any moment
44// in time, via the `SceneGraph()` accessor.
45// + It stores the various Flatland transforms and content generated by
46// commands into a std::unordered_map, and also correctly manages the
47// transform and content lifetimes via reference counting. This allows a
48// given transform or content to stay alive if its parent still holds a
49// reference to it, in the same way the real Flatland implementation would.
50// + The resources returned by `SceneGraph()` that the test uses for
51// inspection are decoupled from the resources managed internally by the
52// `FakeFlatland` itself -- they are a snapshot of the scene graph at that
53// moment in time, with all snapshot state being cloned from the underlying
54// scene graph state. This allows the `FakeFlatland` and test to naturally
55// use `shared_ptr` for reference counting and mimic the real Flatland
56// behavior exactly, instead of an awkward index-based API.
57// + TODO(fxb/85619): Allow injecting {touch,mouse,focus,views} events using
58// the ViewBoundProtocols and {ParentViewport,ChildView}Watcher.
59// + TODO(fxb/85619): Error handling / flatland disconnection is still WIP.
60// FakeFlatland will likely generate a CHECK in any place where the real
61// Flatland would disconnect or send a FlatlandError.
62//
63// The fake deliberately does not attempt to handle certain aspects of the real
64// Flatland implemntation which are complex or burdensome to implement:
65// +Rendering/interacting with Vulkan in any way
66// +Cross-flatland links between Views and Viewports.
68 : public fuchsia::ui::composition::testing::Allocator_TestBase,
69 public fuchsia::ui::composition::testing::Flatland_TestBase {
70 public:
72 std::function<void(fuchsia::ui::composition::PresentArgs)>;
73
75 ~FakeFlatland() override;
76
77 bool is_allocator_connected() const { return allocator_binding_.is_bound(); }
78
79 bool is_flatland_connected() const { return flatland_binding_.is_bound(); }
80
81 const std::string& debug_name() const { return debug_name_; }
82
83 const FakeGraph& graph() { return current_graph_; }
84
85 // Bind this instance's Flatland FIDL channel to the `dispatcher` and allow
86 // processing of incoming FIDL requests.
87 //
88 // This can only be called once.
89 fuchsia::ui::composition::AllocatorHandle ConnectAllocator(
90 async_dispatcher_t* dispatcher = nullptr);
91
92 // Bind this instance's Allocator FIDL channel to the `dispatcher` and allow
93 // processing of incoming FIDL requests.
94 //
95 // This can only be called once.
96 fuchsia::ui::composition::FlatlandHandle ConnectFlatland(
97 async_dispatcher_t* dispatcher = nullptr);
98
99 // Disconnect the Flatland's FIDL channel with an error.
100 // TODO(fxb/85619): Call this internally upon command error, instead of
101 // CHECK'ing.
102 void Disconnect(fuchsia::ui::composition::FlatlandError error);
103
104 // Set a handler for `Present`-related FIDL calls' return values.
105 void SetPresentHandler(PresentHandler present_handler);
106
107 // Fire an `OnNextFrameBegin` event. Call this first after a `Present` in
108 // order to give additional present tokens to the client and simulate scenic's
109 // normal event flow.
111 fuchsia::ui::composition::OnNextFrameBeginValues
112 on_next_frame_begin_values);
113
114 // Fire an `OnFramePresented` event. Call this second after a `Present` in
115 // order to inform the client of retured frames and simulate scenic's normal
116 // event flow.
118 fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info);
119
120 private:
121 struct ParentViewportWatcher : public fuchsia::ui::composition::testing::
122 ParentViewportWatcher_TestBase {
123 public:
124 ParentViewportWatcher(
125 fuchsia::ui::views::ViewCreationToken view_token,
126 fuchsia::ui::views::ViewIdentityOnCreation view_identity,
127 fuchsia::ui::composition::ViewBoundProtocols view_protocols,
128 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
129 parent_viewport_watcher,
130 async_dispatcher_t* dispatcher);
131 ParentViewportWatcher(ParentViewportWatcher&& other);
132 ~ParentViewportWatcher() override;
133
134 // |fuchsia::ui::composition::testing::ParentViewportWatcher_TestBase|
135 void NotImplemented_(const std::string& name) override;
136
137 // |fuchsia::ui::composition::ParentViewportWatcher|
138 void GetLayout(GetLayoutCallback callback) override;
139
140 // |fuchsia::ui::composition::ParentViewportWatcher|
141 void GetStatus(GetStatusCallback callback) override;
142
143 fuchsia::ui::views::ViewCreationToken view_token;
144 fuchsia::ui::views::ViewIdentityOnCreation view_identity;
145 fuchsia::ui::composition::ViewBoundProtocols view_protocols;
146 fidl::Binding<fuchsia::ui::composition::ParentViewportWatcher>
147 parent_viewport_watcher;
148 };
149
150 struct ChildViewWatcher
151 : public fuchsia::ui::composition::testing::ChildViewWatcher_TestBase {
152 public:
153 ChildViewWatcher(
154 fuchsia::ui::views::ViewportCreationToken viewport_token,
155 fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
156 child_view_watcher,
157 async_dispatcher_t* dispatcher);
158 ChildViewWatcher(ChildViewWatcher&& other);
159 ~ChildViewWatcher() override;
160
161 // |fuchsia::ui::composition::testing::ChildViewWatcher_TestBase|
162 void NotImplemented_(const std::string& name) override;
163
164 // |fuchsia::ui::composition::ChildViewWatcher|
165 void GetStatus(GetStatusCallback callback) override;
166
167 fuchsia::ui::views::ViewportCreationToken viewport_token;
168 fidl::Binding<fuchsia::ui::composition::ChildViewWatcher>
169 child_view_watcher;
170 };
171
172 struct ImageBinding {
173 fuchsia::ui::composition::BufferCollectionImportToken import_token;
174 };
175
176 struct BufferCollectionBinding {
177 fuchsia::ui::composition::BufferCollectionExportToken export_token;
178 fuchsia::sysmem::BufferCollectionTokenHandle sysmem_token;
179
180 fuchsia::ui::composition::RegisterBufferCollectionUsage usage;
181 };
182
183 struct GraphBindings {
184 std::optional<std::pair<zx_koid_t, ParentViewportWatcher>> viewport_watcher;
185 std::unordered_map<zx_koid_t, ChildViewWatcher> view_watchers;
186 std::unordered_map<zx_koid_t, ImageBinding> images;
187 std::unordered_map<zx_koid_t, BufferCollectionBinding> buffer_collections;
188 };
189
190 // |fuchsia::ui::composition::testing::Allocator_TestBase|
191 // |fuchsia::ui::composition::testing::Flatland_TestBase|
192 void NotImplemented_(const std::string& name) override;
193
194 // |fuchsia::ui::composition::testing::Allocator|
196 fuchsia::ui::composition::RegisterBufferCollectionArgs args,
197 RegisterBufferCollectionCallback callback) override;
198
199 // |fuchsia::ui::composition::Flatland|
200 void Present(fuchsia::ui::composition::PresentArgs args) override;
201
202 // |fuchsia::ui::composition::Flatland|
203 void CreateView(
204 fuchsia::ui::views::ViewCreationToken token,
205 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
206 parent_viewport_watcher) override;
207
208 // |fuchsia::ui::composition::Flatland|
209 void CreateView2(
210 fuchsia::ui::views::ViewCreationToken token,
211 fuchsia::ui::views::ViewIdentityOnCreation view_identity,
212 fuchsia::ui::composition::ViewBoundProtocols view_protocols,
213 fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
214 parent_viewport_watcher) override;
215
216 // |fuchsia::ui::composition::Flatland|
217 void CreateTransform(
218 fuchsia::ui::composition::TransformId transform_id) override;
219
220 // |fuchsia::ui::composition::Flatland|
221 void SetTranslation(fuchsia::ui::composition::TransformId transform_id,
222 fuchsia::math::Vec translation) override;
223
224 // |fuchsia::ui::composition::Flatland|
225 void SetScale(fuchsia::ui::composition::TransformId transform_id,
226 fuchsia::math::VecF scale) override;
227
228 // |fuchsia::ui::composition::Flatland|
229 void SetOrientation(
230 fuchsia::ui::composition::TransformId transform_id,
231 fuchsia::ui::composition::Orientation orientation) override;
232
233 // |fuchsia::ui::composition::Flatland|
234 void SetOpacity(fuchsia::ui::composition::TransformId transform_id,
235 float value) override;
236
237 // |fuchsia::ui::composition::Flatland|
238 void SetClipBoundary(fuchsia::ui::composition::TransformId transform_id,
239 std::unique_ptr<fuchsia::math::Rect> bounds) override;
240
241 // TODO(fxbug.dev/89111): Re-enable once SDK rolls.
242 // // |fuchsia::ui::composition::Flatland|
243 // void SetImageOpacity(fuchsia::ui::composition::ContentId image_id,
244 // float opacity) override;
245
246 // |fuchsia::ui::composition::Flatland|
247 void AddChild(
248 fuchsia::ui::composition::TransformId parent_transform_id,
249 fuchsia::ui::composition::TransformId child_transform_id) override;
250
251 // |fuchsia::ui::composition::Flatland|
252 void RemoveChild(
253 fuchsia::ui::composition::TransformId parent_transform_id,
254 fuchsia::ui::composition::TransformId child_transform_id) override;
255
256 // |fuchsia::ui::composition::Flatland|
257 void SetContent(fuchsia::ui::composition::TransformId transform_id,
258 fuchsia::ui::composition::ContentId content_id) override;
259
260 // |fuchsia::ui::composition::Flatland|
261 void SetRootTransform(
262 fuchsia::ui::composition::TransformId transform_id) override;
263
264 // |fuchsia::ui::composition::Flatland|
265 void CreateViewport(
266 fuchsia::ui::composition::ContentId viewport_id,
267 fuchsia::ui::views::ViewportCreationToken token,
268 fuchsia::ui::composition::ViewportProperties properties,
269 fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
270 child_view_watcher) override;
271
272 // |fuchsia::ui::composition::Flatland|
273 void CreateImage(
274 fuchsia::ui::composition::ContentId image_id,
275 fuchsia::ui::composition::BufferCollectionImportToken import_token,
276 uint32_t vmo_index,
277 fuchsia::ui::composition::ImageProperties properties) override;
278
279 // |fuchsia::ui::composition::Flatland|
280 void SetImageSampleRegion(fuchsia::ui::composition::ContentId image_id,
281 fuchsia::math::RectF rect) override;
282
283 // |fuchsia::ui::composition::Flatland|
284 void SetImageDestinationSize(fuchsia::ui::composition::ContentId image_id,
285 fuchsia::math::SizeU size) override;
286
287 // |fuchsia::ui::composition::Flatland|
289 fuchsia::ui::composition::ContentId image_id,
290 fuchsia::ui::composition::BlendMode blend_mode) override;
291
292 // |fuchsia::ui::composition::Flatland|
294 fuchsia::ui::composition::ContentId viewport_id,
295 fuchsia::ui::composition::ViewportProperties properties) override;
296
297 // |fuchsia::ui::composition::Flatland|
298 void ReleaseTransform(
299 fuchsia::ui::composition::TransformId transform_id) override;
300
301 // |fuchsia::ui::composition::Flatland|
302 void ReleaseViewport(fuchsia::ui::composition::ContentId viewport_id,
303 ReleaseViewportCallback callback) override;
304
305 // |fuchsia::ui::composition::Flatland|
306 void ReleaseImage(fuchsia::ui::composition::ContentId image_id) override;
307
308 // |fuchsia::ui::composition::Flatland|
309 void SetHitRegions(
310 fuchsia::ui::composition::TransformId transform_id,
311 std::vector<fuchsia::ui::composition::HitRegion> regions) override;
312
313 // |fuchsia::ui::composition::Flatland|
315 fuchsia::ui::composition::TransformId transform_id,
316 fuchsia::ui::composition::HitTestInteraction hit_test) override;
317
318 // |fuchsia::ui::composition::Flatland|
319 void Clear() override;
320
321 // |fuchsia::ui::composition::Flatland|
322 void SetDebugName(std::string debug_name) override;
323
324 fidl::Binding<fuchsia::ui::composition::Allocator> allocator_binding_;
325 fidl::Binding<fuchsia::ui::composition::Flatland> flatland_binding_;
326 GraphBindings graph_bindings_;
327 PresentHandler present_handler_;
328
329 FakeGraph pending_graph_;
330 FakeGraph current_graph_;
331
332 // This map is used to cache parent refs for `AddChild` and `RemoveChild`.
333 //
334 // Ideally we would like to map weak(child) -> weak(parent), but std::weak_ptr
335 // cannot be the Key for an associative container. Instead we key on the raw
336 // parent pointer and store pair(weak(parent), weak(child)) in the map.
337 std::unordered_map<
339 std::pair<std::weak_ptr<FakeTransform>, std::weak_ptr<FakeTransform>>>
340 parents_map_;
341
342 std::string debug_name_;
343
345};
346
347} // namespace flutter_runner::testing
348
349#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_
void SetImageBlendingFunction(fuchsia::ui::composition::ContentId image_id, fuchsia::ui::composition::BlendMode blend_mode) override
void SetHitRegions(fuchsia::ui::composition::TransformId transform_id, std::vector< fuchsia::ui::composition::HitRegion > regions) override
fuchsia::ui::composition::FlatlandHandle ConnectFlatland(async_dispatcher_t *dispatcher=nullptr)
void CreateViewport(fuchsia::ui::composition::ContentId viewport_id, fuchsia::ui::views::ViewportCreationToken token, fuchsia::ui::composition::ViewportProperties properties, fidl::InterfaceRequest< fuchsia::ui::composition::ChildViewWatcher > child_view_watcher) override
void SetOpacity(fuchsia::ui::composition::TransformId transform_id, float value) override
void SetViewportProperties(fuchsia::ui::composition::ContentId viewport_id, fuchsia::ui::composition::ViewportProperties properties) override
void CreateView2(fuchsia::ui::views::ViewCreationToken token, fuchsia::ui::views::ViewIdentityOnCreation view_identity, fuchsia::ui::composition::ViewBoundProtocols view_protocols, fidl::InterfaceRequest< fuchsia::ui::composition::ParentViewportWatcher > parent_viewport_watcher) override
void SetImageSampleRegion(fuchsia::ui::composition::ContentId image_id, fuchsia::math::RectF rect) override
fuchsia::ui::composition::AllocatorHandle ConnectAllocator(async_dispatcher_t *dispatcher=nullptr)
void CreateImage(fuchsia::ui::composition::ContentId image_id, fuchsia::ui::composition::BufferCollectionImportToken import_token, uint32_t vmo_index, fuchsia::ui::composition::ImageProperties properties) override
void SetOrientation(fuchsia::ui::composition::TransformId transform_id, fuchsia::ui::composition::Orientation orientation) override
void ReleaseViewport(fuchsia::ui::composition::ContentId viewport_id, ReleaseViewportCallback callback) override
std::function< void(fuchsia::ui::composition::PresentArgs)> PresentHandler
void SetClipBoundary(fuchsia::ui::composition::TransformId transform_id, std::unique_ptr< fuchsia::math::Rect > bounds) override
void NotImplemented_(const std::string &name) override
void SetScale(fuchsia::ui::composition::TransformId transform_id, fuchsia::math::VecF scale) override
void SetPresentHandler(PresentHandler present_handler)
void SetContent(fuchsia::ui::composition::TransformId transform_id, fuchsia::ui::composition::ContentId content_id) override
void CreateView(fuchsia::ui::views::ViewCreationToken token, fidl::InterfaceRequest< fuchsia::ui::composition::ParentViewportWatcher > parent_viewport_watcher) override
void SetInfiniteHitRegion(fuchsia::ui::composition::TransformId transform_id, fuchsia::ui::composition::HitTestInteraction hit_test) override
void FireOnFramePresentedEvent(fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info)
void SetTranslation(fuchsia::ui::composition::TransformId transform_id, fuchsia::math::Vec translation) override
void AddChild(fuchsia::ui::composition::TransformId parent_transform_id, fuchsia::ui::composition::TransformId child_transform_id) override
void CreateTransform(fuchsia::ui::composition::TransformId transform_id) override
void SetImageDestinationSize(fuchsia::ui::composition::ContentId image_id, fuchsia::math::SizeU size) override
void Present(fuchsia::ui::composition::PresentArgs args) override
void SetDebugName(std::string debug_name) override
const std::string & debug_name() const
void FireOnNextFrameBeginEvent(fuchsia::ui::composition::OnNextFrameBeginValues on_next_frame_begin_values)
void Disconnect(fuchsia::ui::composition::FlatlandError error)
void RegisterBufferCollection(fuchsia::ui::composition::RegisterBufferCollectionArgs args, RegisterBufferCollectionCallback callback) override
void ReleaseImage(fuchsia::ui::composition::ContentId image_id) override
void ReleaseTransform(fuchsia::ui::composition::TransformId transform_id) override
void SetRootTransform(fuchsia::ui::composition::TransformId transform_id) override
void RemoveChild(fuchsia::ui::composition::TransformId parent_transform_id, fuchsia::ui::composition::TransformId child_transform_id) override
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
const char * name
Definition fuchsia.cc:50
std::array< MockImage, 3 > images
str usage
Definition build.py:24
const Scalar scale
decltype(fuchsia::ui::composition::TransformId::value) TransformIdKey