Flutter Engine
FlutterPlatformViewsTest.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 
5 #import <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
7 
8 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
9 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
10 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h"
11 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
12 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
13 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
14 #import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
15 
19 const float kFloatCompareEpsilon = 0.001;
20 
22 @end
24 
25 - (instancetype)init {
26  self = [super init];
27  if (self) {
28  gMockPlatformView = self;
29  }
30  return self;
31 }
32 
33 - (void)dealloc {
34  gMockPlatformView = nil;
35  [super dealloc];
36 }
37 
38 @end
39 
40 @interface FlutterPlatformViewsTestMockFlutterPlatformView : NSObject <FlutterPlatformView>
41 @property(nonatomic, strong) UIView* view;
42 @end
43 
45 
46 - (instancetype)init {
47  if (self = [super init]) {
48  _view = [[FlutterPlatformViewsTestMockPlatformView alloc] init];
49  }
50  return self;
51 }
52 
53 - (void)dealloc {
54  [_view release];
55  _view = nil;
56  [super dealloc];
57 }
58 
59 @end
60 
62  : NSObject <FlutterPlatformViewFactory>
63 @end
64 
66 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
67  viewIdentifier:(int64_t)viewId
68  arguments:(id _Nullable)args {
69  return [[[FlutterPlatformViewsTestMockFlutterPlatformView alloc] init] autorelease];
70 }
71 
72 @end
73 
74 namespace flutter {
75 namespace {
76 class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::Delegate {
77  void OnPlatformViewCreated(std::unique_ptr<Surface> surface) override {}
78  void OnPlatformViewDestroyed() override {}
79  void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {}
80  void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {}
81  void OnPlatformViewDispatchPlatformMessage(fml::RefPtr<PlatformMessage> message) override {}
82  void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet) override {
83  }
84  void OnPlatformViewDispatchSemanticsAction(int32_t id,
86  std::vector<uint8_t> args) override {}
87  void OnPlatformViewSetSemanticsEnabled(bool enabled) override {}
88  void OnPlatformViewSetAccessibilityFeatures(int32_t flags) override {}
89  void OnPlatformViewRegisterTexture(std::shared_ptr<Texture> texture) override {}
90  void OnPlatformViewUnregisterTexture(int64_t texture_id) override {}
91  void OnPlatformViewMarkTextureFrameAvailable(int64_t texture_id) override {}
92 
93  std::unique_ptr<std::vector<std::string>> ComputePlatformViewResolvedLocale(
94  const std::vector<std::string>& supported_locale_data) override {
95  std::unique_ptr<std::vector<std::string>> out = std::make_unique<std::vector<std::string>>();
96  return out;
97  }
98 };
99 
100 } // namespace
101 } // namespace flutter
102 
103 namespace {
104 fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
105  auto thread = std::make_unique<fml::Thread>(name);
106  auto runner = thread->GetTaskRunner();
107  return runner;
108 }
109 } // namespace
110 
111 @interface FlutterPlatformViewsTest : XCTestCase
112 @end
113 
114 @implementation FlutterPlatformViewsTest
115 
116 - (void)testCanCreatePlatformViewWithoutFlutterView {
117  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
118  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
119  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
120  /*platform=*/thread_task_runner,
121  /*raster=*/thread_task_runner,
122  /*ui=*/thread_task_runner,
123  /*io=*/thread_task_runner);
124  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
125  /*delegate=*/mock_delegate,
126  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
127  /*task_runners=*/runners);
128 
129  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
130 
133  flutterPlatformViewsController->RegisterViewFactory(
134  factory, @"MockFlutterPlatformView",
136  FlutterResult result = ^(id result) {
137  };
138  flutterPlatformViewsController->OnMethodCall(
140  methodCallWithMethodName:@"create"
141  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
142  result);
143 
144  XCTAssertNotNil(gMockPlatformView);
145 
146  flutterPlatformViewsController->Reset();
147 }
148 
149 - (void)testChildClippingViewHitTests {
150  ChildClippingView* childClippingView =
151  [[[ChildClippingView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease];
152  UIView* childView = [[[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)] autorelease];
153  [childClippingView addSubview:childView];
154 
155  XCTAssertFalse([childClippingView pointInside:CGPointMake(50, 50) withEvent:nil]);
156  XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 100) withEvent:nil]);
157  XCTAssertFalse([childClippingView pointInside:CGPointMake(100, 99) withEvent:nil]);
158  XCTAssertFalse([childClippingView pointInside:CGPointMake(201, 200) withEvent:nil]);
159  XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 201) withEvent:nil]);
160  XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 200) withEvent:nil]);
161  XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 299) withEvent:nil]);
162 
163  XCTAssertTrue([childClippingView pointInside:CGPointMake(150, 150) withEvent:nil]);
164  XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 100) withEvent:nil]);
165  XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 100) withEvent:nil]);
166  XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 199) withEvent:nil]);
167  XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 199) withEvent:nil]);
168 }
169 
170 - (void)testCompositePlatformView {
171  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
172  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
173  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
174  /*platform=*/thread_task_runner,
175  /*raster=*/thread_task_runner,
176  /*ui=*/thread_task_runner,
177  /*io=*/thread_task_runner);
178  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
179  /*delegate=*/mock_delegate,
180  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
181  /*task_runners=*/runners);
182 
183  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
184 
187  flutterPlatformViewsController->RegisterViewFactory(
188  factory, @"MockFlutterPlatformView",
190  FlutterResult result = ^(id result) {
191  };
192  flutterPlatformViewsController->OnMethodCall(
194  methodCallWithMethodName:@"create"
195  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
196  result);
197 
198  XCTAssertNotNil(gMockPlatformView);
199 
200  UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease];
201  flutterPlatformViewsController->SetFlutterView(mockFlutterView);
202  // Create embedded view params
204  // Layer tree always pushes a screen scale factor to the stack
205  SkMatrix screenScaleMatrix =
206  SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
207  stack.PushTransform(screenScaleMatrix);
208  // Push a translate matrix
209  SkMatrix translateMatrix = SkMatrix::MakeTrans(100, 100);
210  stack.PushTransform(translateMatrix);
211  SkMatrix finalMatrix;
212  finalMatrix.setConcat(screenScaleMatrix, translateMatrix);
213 
214  auto embeddedViewParams =
215  std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
216 
217  flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
218  flutterPlatformViewsController->CompositeEmbeddedView(2);
219  CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
220  toView:mockFlutterView];
221  XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
222  flutterPlatformViewsController->Reset();
223 }
224 
225 - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
226  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
227  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
228  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
229  /*platform=*/thread_task_runner,
230  /*raster=*/thread_task_runner,
231  /*ui=*/thread_task_runner,
232  /*io=*/thread_task_runner);
233  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
234  /*delegate=*/mock_delegate,
235  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
236  /*task_runners=*/runners);
237 
238  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
239 
242  flutterPlatformViewsController->RegisterViewFactory(
243  factory, @"MockFlutterPlatformView",
245  FlutterResult result = ^(id result) {
246  };
247  flutterPlatformViewsController->OnMethodCall(
249  methodCallWithMethodName:@"create"
250  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
251  result);
252 
253  XCTAssertNotNil(gMockPlatformView);
254 
255  UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease];
256  flutterPlatformViewsController->SetFlutterView(mockFlutterView);
257  // Create embedded view params
259  // Layer tree always pushes a screen scale factor to the stack
260  SkMatrix screenScaleMatrix =
261  SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
262  stack.PushTransform(screenScaleMatrix);
263  // Push a rotate matrix
264  SkMatrix rotateMatrix;
265  rotateMatrix.setRotate(10);
266  stack.PushTransform(rotateMatrix);
267  SkMatrix finalMatrix;
268  finalMatrix.setConcat(screenScaleMatrix, rotateMatrix);
269 
270  auto embeddedViewParams =
271  std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
272 
273  flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
274  flutterPlatformViewsController->CompositeEmbeddedView(2);
275  CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
276  toView:mockFlutterView];
277  XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
278  ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
279  // The childclippingview's frame is set based on flow, but the platform view's frame is set based
280  // on quartz. Although they should be the same, but we should tolerate small floating point
281  // errors.
282  XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
284  XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
286  XCTAssertLessThan(
287  fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width),
289  XCTAssertLessThan(
290  fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
292 
293  flutterPlatformViewsController->Reset();
294 }
295 
296 - (void)testClipRect {
297  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
298  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
299  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
300  /*platform=*/thread_task_runner,
301  /*raster=*/thread_task_runner,
302  /*ui=*/thread_task_runner,
303  /*io=*/thread_task_runner);
304  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
305  /*delegate=*/mock_delegate,
306  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
307  /*task_runners=*/runners);
308 
309  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
310 
313  flutterPlatformViewsController->RegisterViewFactory(
314  factory, @"MockFlutterPlatformView",
316  FlutterResult result = ^(id result) {
317  };
318  flutterPlatformViewsController->OnMethodCall(
320  methodCallWithMethodName:@"create"
321  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
322  result);
323 
324  XCTAssertNotNil(gMockPlatformView);
325 
326  UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)] autorelease];
327  flutterPlatformViewsController->SetFlutterView(mockFlutterView);
328  // Create embedded view params
330  // Layer tree always pushes a screen scale factor to the stack
331  SkMatrix screenScaleMatrix =
332  SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
333  stack.PushTransform(screenScaleMatrix);
334  // Push a clip rect
335  SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
336  stack.PushClipRect(rect);
337 
338  auto embeddedViewParams =
339  std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
340 
341  flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
342  flutterPlatformViewsController->CompositeEmbeddedView(2);
343  gMockPlatformView.backgroundColor = UIColor.redColor;
344  XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
345  ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
346  [mockFlutterView addSubview:childClippingView];
347 
348  [mockFlutterView setNeedsLayout];
349  [mockFlutterView layoutIfNeeded];
350 
351  for (int i = 0; i < 10; i++) {
352  for (int j = 0; j < 10; j++) {
353  CGPoint point = CGPointMake(i, j);
354  int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:mockFlutterView];
355  // Edges of the clipping might have a semi transparent pixel, we only check the pixels that
356  // are fully inside the clipped area.
357  CGRect insideClipping = CGRectMake(3, 3, 1, 1);
358  if (CGRectContainsPoint(insideClipping, point)) {
359  XCTAssertEqual(alpha, 255);
360  } else {
361  XCTAssertLessThan(alpha, 255);
362  }
363  }
364  }
365  flutterPlatformViewsController->Reset();
366 }
367 
368 - (void)testClipRRect {
369  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
370  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
371  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
372  /*platform=*/thread_task_runner,
373  /*raster=*/thread_task_runner,
374  /*ui=*/thread_task_runner,
375  /*io=*/thread_task_runner);
376  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
377  /*delegate=*/mock_delegate,
378  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
379  /*task_runners=*/runners);
380 
381  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
382 
385  flutterPlatformViewsController->RegisterViewFactory(
386  factory, @"MockFlutterPlatformView",
388  FlutterResult result = ^(id result) {
389  };
390  flutterPlatformViewsController->OnMethodCall(
392  methodCallWithMethodName:@"create"
393  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
394  result);
395 
396  XCTAssertNotNil(gMockPlatformView);
397 
398  UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)] autorelease];
399  flutterPlatformViewsController->SetFlutterView(mockFlutterView);
400  // Create embedded view params
402  // Layer tree always pushes a screen scale factor to the stack
403  SkMatrix screenScaleMatrix =
404  SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
405  stack.PushTransform(screenScaleMatrix);
406  // Push a clip rrect
407  SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
408  stack.PushClipRRect(rrect);
409 
410  auto embeddedViewParams =
411  std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
412 
413  flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
414  flutterPlatformViewsController->CompositeEmbeddedView(2);
415  gMockPlatformView.backgroundColor = UIColor.redColor;
416  XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
417  ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
418  [mockFlutterView addSubview:childClippingView];
419 
420  [mockFlutterView setNeedsLayout];
421  [mockFlutterView layoutIfNeeded];
422 
423  for (int i = 0; i < 10; i++) {
424  for (int j = 0; j < 10; j++) {
425  CGPoint point = CGPointMake(i, j);
426  int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:mockFlutterView];
427  // Edges of the clipping might have a semi transparent pixel, we only check the pixels that
428  // are fully inside the clipped area.
429  CGRect insideClipping = CGRectMake(3, 3, 4, 4);
430  if (CGRectContainsPoint(insideClipping, point)) {
431  XCTAssertEqual(alpha, 255);
432  } else {
433  XCTAssertLessThan(alpha, 255);
434  }
435  }
436  }
437  flutterPlatformViewsController->Reset();
438 }
439 
440 - (void)testClipPath {
441  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
442  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
443  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
444  /*platform=*/thread_task_runner,
445  /*raster=*/thread_task_runner,
446  /*ui=*/thread_task_runner,
447  /*io=*/thread_task_runner);
448  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
449  /*delegate=*/mock_delegate,
450  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
451  /*task_runners=*/runners);
452 
453  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
454 
457  flutterPlatformViewsController->RegisterViewFactory(
458  factory, @"MockFlutterPlatformView",
460  FlutterResult result = ^(id result) {
461  };
462  flutterPlatformViewsController->OnMethodCall(
464  methodCallWithMethodName:@"create"
465  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
466  result);
467 
468  XCTAssertNotNil(gMockPlatformView);
469 
470  UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)] autorelease];
471  flutterPlatformViewsController->SetFlutterView(mockFlutterView);
472  // Create embedded view params
474  // Layer tree always pushes a screen scale factor to the stack
475  SkMatrix screenScaleMatrix =
476  SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
477  stack.PushTransform(screenScaleMatrix);
478  // Push a clip path
479  SkPath path;
480  path.addRoundRect(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1);
481  stack.PushClipPath(path);
482 
483  auto embeddedViewParams =
484  std::make_unique<flutter::EmbeddedViewParams>(screenScaleMatrix, SkSize::Make(10, 10), stack);
485 
486  flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams));
487  flutterPlatformViewsController->CompositeEmbeddedView(2);
488  gMockPlatformView.backgroundColor = UIColor.redColor;
489  XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]);
490  ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview;
491  [mockFlutterView addSubview:childClippingView];
492 
493  [mockFlutterView setNeedsLayout];
494  [mockFlutterView layoutIfNeeded];
495 
496  for (int i = 0; i < 10; i++) {
497  for (int j = 0; j < 10; j++) {
498  CGPoint point = CGPointMake(i, j);
499  int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:mockFlutterView];
500  // Edges of the clipping might have a semi transparent pixel, we only check the pixels that
501  // are fully inside the clipped area.
502  CGRect insideClipping = CGRectMake(3, 3, 4, 4);
503  if (CGRectContainsPoint(insideClipping, point)) {
504  XCTAssertEqual(alpha, 255);
505  } else {
506  XCTAssertLessThan(alpha, 255);
507  }
508  }
509  }
510  flutterPlatformViewsController->Reset();
511 }
512 
513 - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
514  flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
515  auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
516  flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
517  /*platform=*/thread_task_runner,
518  /*raster=*/thread_task_runner,
519  /*ui=*/thread_task_runner,
520  /*io=*/thread_task_runner);
521  auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
522  /*delegate=*/mock_delegate,
523  /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
524  /*task_runners=*/runners);
525 
526  auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>();
527 
530  flutterPlatformViewsController->RegisterViewFactory(
531  factory, @"MockFlutterPlatformView",
533  FlutterResult result = ^(id result) {
534  };
535  flutterPlatformViewsController->OnMethodCall(
537  methodCallWithMethodName:@"create"
538  arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
539  result);
540 
541  XCTAssertNotNil(gMockPlatformView);
542 
543  // Find touch inteceptor view
544  UIView* touchInteceptorView = gMockPlatformView;
545  while (touchInteceptorView != nil &&
546  ![touchInteceptorView isKindOfClass:[FlutterTouchInterceptingView class]]) {
547  touchInteceptorView = touchInteceptorView.superview;
548  }
549  XCTAssertNotNil(touchInteceptorView);
550 
551  // Find ForwardGestureRecognizer
552  UIGestureRecognizer* forwardGectureRecognizer = nil;
553  for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
554  if ([gestureRecognizer isKindOfClass:NSClassFromString(@"ForwardingGestureRecognizer")]) {
555  forwardGectureRecognizer = gestureRecognizer;
556  break;
557  }
558  }
559 
560  // Before setting flutter view controller, events are not dispatched.
561  NSSet* touches1 = OCMClassMock([NSSet class]);
562  UIEvent* event1 = OCMClassMock([UIEvent class]);
563  UIViewController* mockFlutterViewContoller = OCMClassMock([UIViewController class]);
564  [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
565  OCMReject([mockFlutterViewContoller touchesBegan:touches1 withEvent:event1]);
566 
567  // Set flutter view controller allows events to be dispatched.
568  NSSet* touches2 = OCMClassMock([NSSet class]);
569  UIEvent* event2 = OCMClassMock([UIEvent class]);
570  flutterPlatformViewsController->SetFlutterViewController(mockFlutterViewContoller);
571  [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
572  OCMVerify([mockFlutterViewContoller touchesBegan:touches2 withEvent:event2]);
573 
574  flutterPlatformViewsController->Reset();
575 }
576 
577 - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
578  unsigned char pixel[4] = {0};
579 
580  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
581 
582  // Draw the pixel on `point` in the context.
583  CGContextRef context = CGBitmapContextCreate(
584  pixel, 1, 1, 8, 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
585  CGContextTranslateCTM(context, -point.x, -point.y);
586  [view.layer renderInContext:context];
587 
588  CGContextRelease(context);
589  CGColorSpaceRelease(colorSpace);
590  // Get the alpha from the pixel that we just rendered.
591  return pixel[3];
592 }
593 
594 @end
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
#define FLUTTER_ASSERT_NOT_ARC
Definition: FlutterMacros.h:45
void PushClipPath(const SkPath &path)
void PushTransform(const SkMatrix &matrix)
std::function< void()> closure
Definition: closure.h:14
const float kFloatCompareEpsilon
SemanticsAction action
void(^ FlutterResult)(id _Nullable result)
void PushClipRect(const SkRect &rect)
void PushClipRRect(const SkRRect &rrect)
const char * name
Definition: fuchsia.cc:50
static FlutterPlatformViewsTestMockPlatformView * gMockPlatformView
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66