Flutter macOS Embedder
FlutterMutatorViewTest.mm
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 
6 
7 #include "third_party/googletest/googletest/include/gtest/gtest.h"
8 
10 
12 
13 @property(readonly, nonatomic, nonnull) NSMutableArray<NSView*>* pathClipViews;
14 @property(readonly, nonatomic, nullable) NSView* platformViewContainer;
15 
16 @end
17 
18 static constexpr float kMaxErr = 1e-10;
19 
20 namespace {
21 void ApplyFlutterLayer(FlutterMutatorView* view,
22  FlutterSize size,
23  const std::vector<FlutterPlatformViewMutation>& mutations) {
24  flutter::PlatformViewLayer layer(0, // identifier
25  mutations,
26  // Offset is ignored by mutator view, the bounding rect is
27  // determined by width and transform.
28  FlutterPoint{0, 0}, // offset
29  size);
30 
31  [view applyFlutterLayer:&layer];
32 }
33 
34 // Expect that each element within two CATransform3Ds is within an error bound.
35 //
36 // In order to avoid architecture-specific floating point differences we don't check for exact
37 // equality using, for example, CATransform3DEqualToTransform.
38 void ExpectTransform3DEqual(const CATransform3D& t, const CATransform3D& u) {
39  EXPECT_NEAR(t.m11, u.m11, kMaxErr);
40  EXPECT_NEAR(t.m12, u.m12, kMaxErr);
41  EXPECT_NEAR(t.m13, u.m13, kMaxErr);
42  EXPECT_NEAR(t.m14, u.m14, kMaxErr);
43 
44  EXPECT_NEAR(t.m21, u.m21, kMaxErr);
45  EXPECT_NEAR(t.m22, u.m22, kMaxErr);
46  EXPECT_NEAR(t.m23, u.m23, kMaxErr);
47  EXPECT_NEAR(t.m24, u.m24, kMaxErr);
48 
49  EXPECT_NEAR(t.m31, u.m31, kMaxErr);
50  EXPECT_NEAR(t.m32, u.m32, kMaxErr);
51  EXPECT_NEAR(t.m33, u.m33, kMaxErr);
52  EXPECT_NEAR(t.m34, u.m34, kMaxErr);
53 
54  EXPECT_NEAR(t.m41, u.m41, kMaxErr);
55  EXPECT_NEAR(t.m42, u.m42, kMaxErr);
56  EXPECT_NEAR(t.m43, u.m43, kMaxErr);
57  EXPECT_NEAR(t.m44, u.m44, kMaxErr);
58 }
59 } // namespace
60 
61 TEST(FlutterMutatorViewTest, BasicFrameIsCorrect) {
62  NSView* platformView = [[NSView alloc] init];
63  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
64 
65  EXPECT_EQ(mutatorView.platformView, platformView);
66 
67  std::vector<FlutterPlatformViewMutation> mutations{
68  {
69  .type = kFlutterPlatformViewMutationTypeTransformation,
70  .transformation =
71  FlutterTransformation{
72  .scaleX = 1,
73  .transX = 100,
74  .scaleY = 1,
75  .transY = 50,
76  },
77  },
78  };
79 
80  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
81 
82  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
83  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
84  EXPECT_EQ(mutatorView.pathClipViews.count, 0ull);
85  EXPECT_NE(mutatorView.platformViewContainer, nil);
86 }
87 
88 TEST(FlutterMutatorViewTest, ClipsToBounds) {
89  NSView* platformView = [[NSView alloc] init];
90  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
91  EXPECT_TRUE(mutatorView.clipsToBounds);
92 }
93 
94 TEST(FlutterMutatorViewTest, TransformedFrameIsCorrect) {
95  NSView* platformView = [[NSView alloc] init];
96  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
97  NSView* mutatorViewParent = [[NSView alloc] init];
98  mutatorViewParent.wantsLayer = YES;
99  mutatorViewParent.layer.contentsScale = 2.0;
100  [mutatorViewParent addSubview:mutatorView];
101 
102  std::vector<FlutterPlatformViewMutation> mutations{
103  {
104  .type = kFlutterPlatformViewMutationTypeTransformation,
105  .transformation =
106  FlutterTransformation{
107  .scaleX = 2,
108  .scaleY = 2,
109  },
110  },
111  {
112  .type = kFlutterPlatformViewMutationTypeTransformation,
113  .transformation =
114  FlutterTransformation{
115  .scaleX = 1,
116  .transX = 100,
117  .scaleY = 1,
118  .transY = 50,
119  },
120  },
121  {
122  .type = kFlutterPlatformViewMutationTypeTransformation,
123  .transformation =
124  FlutterTransformation{
125  .scaleX = 1.5,
126  .transX = -7.5,
127  .scaleY = 1.5,
128  .transY = -5,
129  },
130  },
131  };
132 
133  // PlatformView size form engine comes in physical pixels
134  ApplyFlutterLayer(mutatorView, FlutterSize{30 * 2, 20 * 2}, mutations);
135  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(92.5, 45, 45, 30)));
136  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
137 
138  ExpectTransform3DEqual(mutatorView.platformViewContainer.layer.sublayerTransform,
139  CATransform3DMakeScale(1.5, 1.5, 1));
140 }
141 
142 TEST(FlutterMutatorViewTest, FrameWithLooseClipIsCorrect) {
143  NSView* platformView = [[NSView alloc] init];
144  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
145 
146  EXPECT_EQ(mutatorView.platformView, platformView);
147 
148  std::vector<FlutterPlatformViewMutation> mutations{
149  {
150  .type = kFlutterPlatformViewMutationTypeClipRect,
151  .clip_rect = FlutterRect{80, 40, 200, 100},
152  },
153  {
154  .type = kFlutterPlatformViewMutationTypeTransformation,
155  .transformation =
156  FlutterTransformation{
157  .scaleX = 1,
158  .transX = 100,
159  .scaleY = 1,
160  .transY = 50,
161  },
162  },
163  };
164 
165  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
166 
167  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
168  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
169 }
170 
171 TEST(FlutterMutatorViewTest, FrameWithTightClipIsCorrect) {
172  NSView* platformView = [[NSView alloc] init];
173  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
174 
175  EXPECT_EQ(mutatorView.platformView, platformView);
176 
177  std::vector<FlutterPlatformViewMutation> mutations{
178  {
179  .type = kFlutterPlatformViewMutationTypeClipRect,
180  .clip_rect = FlutterRect{80, 40, 200, 100},
181  },
182  {
183  .type = kFlutterPlatformViewMutationTypeClipRect,
184  .clip_rect = FlutterRect{110, 55, 120, 65},
185  },
186  {
187  .type = kFlutterPlatformViewMutationTypeTransformation,
188  .transformation =
189  FlutterTransformation{
190  .scaleX = 1,
191  .transX = 100,
192  .scaleY = 1,
193  .transY = 50,
194  },
195  },
196  };
197 
198  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
199 
200  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
201  EXPECT_TRUE(
202  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -5, 30, 20)));
203  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
204 }
205 
206 TEST(FlutterMutatorViewTest, FrameWithTightClipAndTransformIsCorrect) {
207  NSView* platformView = [[NSView alloc] init];
208  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
209  NSView* mutatorViewParent = [[NSView alloc] init];
210  mutatorViewParent.wantsLayer = YES;
211  mutatorViewParent.layer.contentsScale = 2.0;
212  [mutatorViewParent addSubview:mutatorView];
213 
214  std::vector<FlutterPlatformViewMutation> mutations{
215  {
216  .type = kFlutterPlatformViewMutationTypeTransformation,
217  .transformation =
218  FlutterTransformation{
219  .scaleX = 2,
220  .scaleY = 2,
221  },
222  },
223  {
224  .type = kFlutterPlatformViewMutationTypeClipRect,
225  .clip_rect = FlutterRect{80, 40, 200, 100},
226  },
227  {
228  .type = kFlutterPlatformViewMutationTypeClipRect,
229  .clip_rect = FlutterRect{110, 55, 120, 65},
230  },
231  {
232  .type = kFlutterPlatformViewMutationTypeTransformation,
233  .transformation =
234  FlutterTransformation{
235  .scaleX = 1,
236  .transX = 100,
237  .scaleY = 1,
238  .transY = 50,
239  },
240  },
241  {
242  .type = kFlutterPlatformViewMutationTypeTransformation,
243  .transformation =
244  FlutterTransformation{
245  .scaleX = 1.5,
246  .transX = -7.5,
247  .scaleY = 1.5,
248  .transY = -5,
249  },
250  },
251  };
252 
253  ApplyFlutterLayer(mutatorView, FlutterSize{30 * 2, 20 * 2}, mutations);
254 
255  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
256  EXPECT_TRUE(
257  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-17.5, -10, 45, 30)));
258  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
259 }
260 
261 // Rounded rectangle without hitting the corner
262 TEST(FlutterMutatorViewTest, RoundRectClipsToSimpleRectangle) {
263  NSView* platformView = [[NSView alloc] init];
264  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
265 
266  std::vector<FlutterPlatformViewMutation> mutations{
267  {
268  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
269  .clip_rounded_rect =
270  FlutterRoundedRect{
271  .rect = FlutterRect{110, 30, 120, 90},
272  .upper_left_corner_radius = FlutterSize{10, 10},
273  .upper_right_corner_radius = FlutterSize{10, 10},
274  .lower_right_corner_radius = FlutterSize{10, 10},
275  .lower_left_corner_radius = FlutterSize{10, 10},
276  },
277  },
278  {
279  .type = kFlutterPlatformViewMutationTypeTransformation,
280  .transformation =
281  FlutterTransformation{
282  .scaleX = 1,
283  .transX = 100,
284  .scaleY = 1,
285  .transY = 50,
286  },
287  },
288  };
289 
290  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
291 
292  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 50, 10, 20)));
293  EXPECT_TRUE(
294  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, 0, 30, 20)));
295  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
296  EXPECT_EQ(mutatorView.pathClipViews.count, 0ul);
297 }
298 
299 // Ensure that the mutator view, clip views, and container all use a flipped y axis. The transforms
300 // sent from the framework assume this, and so aside from the consistency with every other embedder,
301 // we can avoid a lot of extra math.
302 TEST(FlutterMutatorViewTest, ViewsSetIsFlipped) {
303  NSView* platformView = [[NSView alloc] init];
304  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
305 
306  std::vector<FlutterPlatformViewMutation> mutations{
307  {
308  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
309  .clip_rounded_rect =
310  FlutterRoundedRect{
311  .rect = FlutterRect{110, 60, 150, 150},
312  .upper_left_corner_radius = FlutterSize{10, 10},
313  .upper_right_corner_radius = FlutterSize{10, 10},
314  .lower_right_corner_radius = FlutterSize{10, 10},
315  .lower_left_corner_radius = FlutterSize{10, 10},
316  },
317  },
318  {
319  .type = kFlutterPlatformViewMutationTypeTransformation,
320  .transformation =
321  FlutterTransformation{
322  .scaleX = 1,
323  .transX = 100,
324  .scaleY = 1,
325  .transY = 50,
326  },
327  },
328  };
329 
330  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
331 
332  EXPECT_TRUE(mutatorView.isFlipped);
333  ASSERT_EQ(mutatorView.pathClipViews.count, 1ul);
334  EXPECT_TRUE(mutatorView.pathClipViews.firstObject.isFlipped);
335  EXPECT_TRUE(mutatorView.platformViewContainer.isFlipped);
336 }
337 
338 TEST(FlutterMutatorViewTest, RectsClipsToPathWhenRotated) {
339  NSView* platformView = [[NSView alloc] init];
340  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
341  std::vector<FlutterPlatformViewMutation> mutations{
342  {
343  .type = kFlutterPlatformViewMutationTypeTransformation,
344  // Roation M_PI / 8
345  .transformation =
346  FlutterTransformation{
347  .scaleX = 0.9238795325112867,
348  .skewX = -0.3826834323650898,
349  .skewY = 0.3826834323650898,
350  .scaleY = 0.9238795325112867,
351  },
352  },
353  {
354  .type = kFlutterPlatformViewMutationTypeClipRect,
355  .clip_rect = FlutterRect{110, 60, 150, 150},
356  },
357  {
358  .type = kFlutterPlatformViewMutationTypeTransformation,
359  .transformation =
360  FlutterTransformation{
361  .scaleX = 1,
362  .transX = 100,
363  .scaleY = 1,
364  .transY = 50,
365  },
366  },
367  };
368  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
369  EXPECT_EQ(mutatorView.pathClipViews.count, 1ul);
370  EXPECT_NEAR(mutatorView.platformViewContainer.frame.size.width, 35.370054622640396, kMaxErr);
371  EXPECT_NEAR(mutatorView.platformViewContainer.frame.size.height, 29.958093621178421, kMaxErr);
372 }
373 
374 TEST(FlutterMutatorViewTest, RoundRectClipsToPath) {
375  NSView* platformView = [[NSView alloc] init];
376  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
377 
378  std::vector<FlutterPlatformViewMutation> mutations{
379  {
380  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
381  .clip_rounded_rect =
382  FlutterRoundedRect{
383  .rect = FlutterRect{110, 60, 150, 150},
384  .upper_left_corner_radius = FlutterSize{10, 10},
385  .upper_right_corner_radius = FlutterSize{10, 10},
386  .lower_right_corner_radius = FlutterSize{10, 10},
387  .lower_left_corner_radius = FlutterSize{10, 10},
388  },
389  },
390  {
391  .type = kFlutterPlatformViewMutationTypeTransformation,
392  .transformation =
393  FlutterTransformation{
394  .scaleX = 1,
395  .transX = 100,
396  .scaleY = 1,
397  .transY = 50,
398  },
399  },
400  };
401 
402  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
403 
404  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
405  EXPECT_TRUE(
406  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
407  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
408  EXPECT_EQ(mutatorView.pathClipViews.count, 1ul);
409  ExpectTransform3DEqual(mutatorView.pathClipViews.firstObject.layer.mask.transform,
410  CATransform3DMakeTranslation(-100, -50, 0));
411 }
412 
413 TEST(FlutterMutatorViewTest, PathClipViewsAreAddedAndRemoved) {
414  NSView* platformView = [[NSView alloc] init];
415  FlutterMutatorView* mutatorView = [[FlutterMutatorView alloc] initWithPlatformView:platformView];
416 
417  std::vector<FlutterPlatformViewMutation> mutations{
418  {
419  .type = kFlutterPlatformViewMutationTypeTransformation,
420  .transformation =
421  FlutterTransformation{
422  .scaleX = 1,
423  .transX = 100,
424  .scaleY = 1,
425  .transY = 50,
426  },
427  },
428  };
429 
430  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
431 
432  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
433  EXPECT_EQ(mutatorView.pathClipViews.count, 0ull);
434 
435  std::vector<FlutterPlatformViewMutation> mutations2{
436  {
437  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
438  .clip_rounded_rect =
439  FlutterRoundedRect{
440  .rect = FlutterRect{110, 60, 150, 150},
441  .upper_left_corner_radius = FlutterSize{10, 10},
442  .upper_right_corner_radius = FlutterSize{10, 10},
443  .lower_right_corner_radius = FlutterSize{10, 10},
444  .lower_left_corner_radius = FlutterSize{10, 10},
445  },
446  },
447  {
448  .type = kFlutterPlatformViewMutationTypeTransformation,
449  .transformation =
450  FlutterTransformation{
451  .scaleX = 1,
452  .transX = 100,
453  .scaleY = 1,
454  .transY = 50,
455  },
456  },
457  };
458 
459  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations2);
460 
461  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
462  EXPECT_TRUE(
463  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
464  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
465  EXPECT_EQ(mutatorView.pathClipViews.count, 1ul);
466 
467  EXPECT_EQ(platformView.superview, mutatorView.platformViewContainer);
468  EXPECT_EQ(mutatorView.platformViewContainer.superview, mutatorView.pathClipViews[0]);
469  EXPECT_EQ(mutatorView.pathClipViews[0].superview, mutatorView);
470 
471  std::vector<FlutterPlatformViewMutation> mutations3{
472  {
473  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
474  .clip_rounded_rect =
475  FlutterRoundedRect{
476  .rect = FlutterRect{110, 55, 150, 150},
477  .upper_left_corner_radius = FlutterSize{10, 10},
478  .upper_right_corner_radius = FlutterSize{10, 10},
479  .lower_right_corner_radius = FlutterSize{10, 10},
480  .lower_left_corner_radius = FlutterSize{10, 10},
481  },
482  },
483  {
484  .type = kFlutterPlatformViewMutationTypeClipRoundedRect,
485  .clip_rounded_rect =
486  FlutterRoundedRect{
487  .rect = FlutterRect{30, 30, 120, 65},
488  .upper_left_corner_radius = FlutterSize{10, 10},
489  .upper_right_corner_radius = FlutterSize{10, 10},
490  .lower_right_corner_radius = FlutterSize{10, 10},
491  .lower_left_corner_radius = FlutterSize{10, 10},
492  },
493  },
494  {
495  .type = kFlutterPlatformViewMutationTypeTransformation,
496  .transformation =
497  FlutterTransformation{
498  .scaleX = 1,
499  .transX = 100,
500  .scaleY = 1,
501  .transY = 50,
502  },
503  },
504  };
505 
506  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations3);
507 
508  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 55, 10, 10)));
509  EXPECT_TRUE(
510  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -5, 30, 20)));
511  EXPECT_EQ(mutatorView.pathClipViews.count, 2ul);
512 
513  EXPECT_EQ(platformView.superview, mutatorView.platformViewContainer);
514  EXPECT_EQ(mutatorView.platformViewContainer.superview, mutatorView.pathClipViews[1]);
515  EXPECT_EQ(mutatorView.pathClipViews[1].superview, mutatorView.pathClipViews[0]);
516  EXPECT_EQ(mutatorView.pathClipViews[0].superview, mutatorView);
517 
518  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations2);
519 
520  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(110, 60, 20, 10)));
521  EXPECT_TRUE(
522  CGRectEqualToRect(mutatorView.subviews.firstObject.frame, CGRectMake(-10, -10, 30, 20)));
523  EXPECT_TRUE(CGRectEqualToRect(platformView.frame, CGRectMake(0, 0, 30, 20)));
524  EXPECT_EQ(mutatorView.pathClipViews.count, 1ul);
525 
526  EXPECT_EQ(platformView.superview, mutatorView.platformViewContainer);
527  EXPECT_EQ(mutatorView.platformViewContainer.superview, mutatorView.pathClipViews[0]);
528  EXPECT_EQ(mutatorView.pathClipViews[0].superview, mutatorView);
529 
530  ApplyFlutterLayer(mutatorView, FlutterSize{30, 20}, mutations);
531 
532  EXPECT_TRUE(CGRectEqualToRect(mutatorView.frame, CGRectMake(100, 50, 30, 20)));
533  EXPECT_EQ(mutatorView.pathClipViews.count, 0ull);
534 }
FlutterMutatorView.h
FlutterMutatorView
Definition: FlutterMutatorView.h:42
-[FlutterMutatorView applyFlutterLayer:]
void applyFlutterLayer:(nonnull const flutter::PlatformViewLayer *layer)
FlutterMutatorView::platformView
NSView * platformView
Returns wrapped platform view.
Definition: FlutterMutatorView.h:48
FlutterMutatorView(Private)::pathClipViews
NSMutableArray< NSView * > * pathClipViews
Definition: FlutterMutatorViewTest.mm:13
kMaxErr
static constexpr float kMaxErr
Definition: FlutterMutatorViewTest.mm:18
FlutterMutatorView(Private)::platformViewContainer
NSView * platformViewContainer
Definition: FlutterMutatorViewTest.mm:14
FlutterMutatorView(Private)
Definition: FlutterMutatorViewTest.mm:11
NSView+ClipsToBounds.h
TEST
TEST(FlutterMutatorViewTest, BasicFrameIsCorrect)
Definition: FlutterMutatorViewTest.mm:61
flutter::PlatformViewLayer
Represents a platform view layer, including all mutations.
Definition: FlutterMutatorView.h:16