5 #include "display_list/geometry/dl_geometry_types.h"
8 #import <OCMock/OCMock.h>
9 #import <UIKit/UIKit.h>
10 #import <WebKit/WebKit.h>
11 #import <XCTest/XCTest.h>
15 #include "flutter/display_list/effects/dl_image_filters.h"
16 #include "flutter/fml/synchronization/count_down_latch.h"
17 #include "flutter/fml/thread.h"
37 - (instancetype)init {
57 @property(nonatomic, strong) NSMutableArray<NSNumber*>* toggleHistory;
61 - (instancetype)init {
64 _toggleHistory = [NSMutableArray array];
68 - (void)setEnabled:(BOOL)enabled {
69 [
super setEnabled:enabled];
70 [
self.toggleHistory addObject:@(enabled)];
82 @property(nonatomic, strong) UIView* view;
83 @property(nonatomic, assign) BOOL viewCreated;
88 - (instancetype)init {
89 if (
self = [super init]) {
97 [
self checkViewCreatedOnce];
101 - (void)checkViewCreatedOnce {
105 self.viewCreated = YES;
114 : NSObject <FlutterPlatformViewFactory>
119 viewIdentifier:(int64_t)viewId
120 arguments:(
id _Nullable)args {
127 @property(nonatomic, strong) UIView* view;
128 @property(nonatomic, assign) BOOL viewCreated;
132 - (instancetype)init {
133 if (
self = [super init]) {
134 _view = [[WKWebView alloc] init];
142 [
self checkViewCreatedOnce];
146 - (void)checkViewCreatedOnce {
150 self.viewCreated = YES;
162 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
163 viewIdentifier:(int64_t)viewId
164 arguments:(
id _Nullable)args {
173 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
174 viewIdentifier:(int64_t)viewId
175 arguments:(
id _Nullable)args {
182 @property(nonatomic, strong) UIView* view;
183 @property(nonatomic, assign) BOOL viewCreated;
187 - (instancetype)init {
188 if (
self = [super init]) {
189 _view = [[UIView alloc] init];
190 [_view addSubview:[[WKWebView alloc] init]];
198 [
self checkViewCreatedOnce];
202 - (void)checkViewCreatedOnce {
206 self.viewCreated = YES;
218 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
219 viewIdentifier:(int64_t)viewId
220 arguments:(
id _Nullable)args {
226 @property(nonatomic, strong) UIView* view;
227 @property(nonatomic, assign) BOOL viewCreated;
231 - (instancetype)init {
232 if (
self = [super init]) {
233 _view = [[UIView alloc] init];
234 UIView* childView = [[UIView alloc] init];
235 [_view addSubview:childView];
236 [childView addSubview:[[WKWebView alloc] init]];
244 [
self checkViewCreatedOnce];
248 - (void)checkViewCreatedOnce {
252 self.viewCreated = YES;
257 : NSObject <FlutterPlatformViewFactory>
262 viewIdentifier:(int64_t)viewId
263 arguments:(
id _Nullable)args {
270 class FlutterPlatformViewsTestMockPlatformViewDelegate :
public PlatformView::Delegate {
272 void OnPlatformViewCreated(std::unique_ptr<Surface> surface)
override {}
273 void OnPlatformViewDestroyed()
override {}
274 void OnPlatformViewScheduleFrame()
override {}
275 void OnPlatformViewAddView(int64_t view_id,
276 const ViewportMetrics& viewport_metrics,
277 AddViewCallback callback)
override {}
278 void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback)
override {}
279 void OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event)
override {};
280 void OnPlatformViewSetNextFrameCallback(
const fml::closure& closure)
override {}
281 void OnPlatformViewSetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics)
override {}
282 const flutter::Settings& OnPlatformViewGetSettings()
const override {
return settings_; }
283 void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message)
override {}
284 void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet)
override {
286 void OnPlatformViewDispatchSemanticsAction(int64_t view_id,
288 SemanticsAction action,
289 fml::MallocMapping args)
override {}
290 void OnPlatformViewSetSemanticsEnabled(
bool enabled)
override {}
291 void OnPlatformViewSetAccessibilityFeatures(int32_t flags)
override {}
292 void OnPlatformViewRegisterTexture(std::shared_ptr<Texture> texture)
override {}
293 void OnPlatformViewUnregisterTexture(int64_t
texture_id)
override {}
294 void OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id)
override {}
296 void LoadDartDeferredLibrary(intptr_t loading_unit_id,
297 std::unique_ptr<const fml::Mapping> snapshot_data,
298 std::unique_ptr<const fml::Mapping> snapshot_instructions)
override {
300 void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
301 const std::string error_message,
302 bool transient)
override {}
303 void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
304 flutter::AssetResolver::AssetResolverType type)
override {}
309 BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2) {
310 const CGFloat epsilon = 0.01;
311 return std::abs(radius1 - radius2) < epsilon;
323 fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
324 fml::MessageLoop::EnsureInitializedForCurrentThread();
325 return fml::MessageLoop::GetCurrent().GetTaskRunner();
329 - (void)testFlutterViewOnlyCreateOnceInOneFrame {
330 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
332 flutter::TaskRunners runners(
self.name.UTF8String,
333 GetDefaultTaskRunner(),
334 GetDefaultTaskRunner(),
335 GetDefaultTaskRunner(),
336 GetDefaultTaskRunner());
339 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
340 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
343 flutterPlatformViewsController,
346 std::make_shared<fml::SyncSwitch>());
350 [flutterPlatformViewsController
352 withId:@"MockFlutterPlatformView"
356 [flutterPlatformViewsController
360 @"viewType" : @"MockFlutterPlatformView"
363 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
364 flutterPlatformViewsController.
flutterView = flutterView;
366 flutter::MutatorsStack stack;
368 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
369 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
370 stack.PushTransform(screenScaleMatrix);
372 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
373 stack.PushTransform(translateMatrix);
374 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
376 auto embeddedViewParams =
377 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
379 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
380 withParams:std::move(embeddedViewParams)];
384 [flutterPlatformViewsController
reset];
387 - (void)testCanCreatePlatformViewWithoutFlutterView {
388 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
390 flutter::TaskRunners runners(
self.name.UTF8String,
391 GetDefaultTaskRunner(),
392 GetDefaultTaskRunner(),
393 GetDefaultTaskRunner(),
394 GetDefaultTaskRunner());
397 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
398 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
401 flutterPlatformViewsController,
404 std::make_shared<fml::SyncSwitch>());
408 [flutterPlatformViewsController
410 withId:@"MockFlutterPlatformView"
414 [flutterPlatformViewsController
418 @"viewType" : @"MockFlutterPlatformView"
425 - (void)testChildClippingViewHitTests {
428 UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
429 [childClippingView addSubview:childView];
431 XCTAssertFalse([childClippingView pointInside:CGPointMake(50, 50) withEvent:nil]);
432 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 100) withEvent:nil]);
433 XCTAssertFalse([childClippingView pointInside:CGPointMake(100, 99) withEvent:nil]);
434 XCTAssertFalse([childClippingView pointInside:CGPointMake(201, 200) withEvent:nil]);
435 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 201) withEvent:nil]);
436 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 200) withEvent:nil]);
437 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 299) withEvent:nil]);
439 XCTAssertTrue([childClippingView pointInside:CGPointMake(150, 150) withEvent:nil]);
440 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 100) withEvent:nil]);
441 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 100) withEvent:nil]);
442 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 199) withEvent:nil]);
443 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 199) withEvent:nil]);
446 - (void)testReleasesBackdropFilterSubviewsOnChildClippingViewDealloc {
447 __weak NSMutableArray<UIVisualEffectView*>* weakBackdropFilterSubviews = nil;
448 __weak UIVisualEffectView* weakVisualEffectView1 = nil;
449 __weak UIVisualEffectView* weakVisualEffectView2 = nil;
453 UIVisualEffectView* visualEffectView1 = [[UIVisualEffectView alloc]
454 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
455 weakVisualEffectView1 = visualEffectView1;
460 visualEffectView:visualEffectView1];
465 UIVisualEffectView* visualEffectView2 = [[UIVisualEffectView alloc]
466 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
467 weakVisualEffectView2 = visualEffectView2;
472 visualEffectView:visualEffectView2];
476 XCTAssertNotNil(weakBackdropFilterSubviews);
479 XCTAssertNil(weakBackdropFilterSubviews);
480 XCTAssertNil(weakVisualEffectView1);
481 XCTAssertNil(weakVisualEffectView2);
484 - (void)testApplyBackdropFilter {
485 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
487 flutter::TaskRunners runners(
self.name.UTF8String,
488 GetDefaultTaskRunner(),
489 GetDefaultTaskRunner(),
490 GetDefaultTaskRunner(),
491 GetDefaultTaskRunner());
494 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
495 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
498 flutterPlatformViewsController,
501 std::make_shared<fml::SyncSwitch>());
505 [flutterPlatformViewsController
507 withId:@"MockFlutterPlatformView"
511 [flutterPlatformViewsController
515 @"viewType" : @"MockFlutterPlatformView"
521 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
522 flutterPlatformViewsController.
flutterView = flutterView;
524 flutter::MutatorsStack stack;
526 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
527 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
528 stack.PushTransform(screenScaleMatrix);
530 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
531 stack.PushBackdropFilter(filter,
532 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
534 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
535 screenScaleMatrix, flutter::DlSize(10, 10), stack);
537 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
538 withParams:std::move(embeddedViewParams)];
539 [flutterPlatformViewsController
545 [flutterView addSubview:childClippingView];
547 [flutterView setNeedsLayout];
548 [flutterView layoutIfNeeded];
551 NSUInteger numberOfExpectedVisualEffectView = 0;
552 for (UIView* subview in childClippingView.subviews) {
553 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
556 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
557 if ([
self validateOneVisualEffectView:subview
558 expectedFrame:CGRectMake(0, 0, 10, 10)
560 numberOfExpectedVisualEffectView++;
563 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
566 - (void)testApplyBackdropFilterWithCorrectFrame {
567 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
569 flutter::TaskRunners runners(
self.name.UTF8String,
570 GetDefaultTaskRunner(),
571 GetDefaultTaskRunner(),
572 GetDefaultTaskRunner(),
573 GetDefaultTaskRunner());
576 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
577 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
580 flutterPlatformViewsController,
583 std::make_shared<fml::SyncSwitch>());
587 [flutterPlatformViewsController
589 withId:@"MockFlutterPlatformView"
593 [flutterPlatformViewsController
597 @"viewType" : @"MockFlutterPlatformView"
603 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
604 flutterPlatformViewsController.
flutterView = flutterView;
606 flutter::MutatorsStack stack;
608 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
609 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
610 stack.PushTransform(screenScaleMatrix);
612 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
613 stack.PushBackdropFilter(filter,
614 flutter::DlRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
616 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
617 screenScaleMatrix, flutter::DlSize(5, 10), stack);
619 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
620 withParams:std::move(embeddedViewParams)];
621 [flutterPlatformViewsController
627 [flutterView addSubview:childClippingView];
629 [flutterView setNeedsLayout];
630 [flutterView layoutIfNeeded];
633 NSUInteger numberOfExpectedVisualEffectView = 0;
634 for (UIView* subview in childClippingView.subviews) {
635 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
638 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
639 if ([
self validateOneVisualEffectView:subview
640 expectedFrame:CGRectMake(0, 0, 5, 8)
642 numberOfExpectedVisualEffectView++;
645 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
648 - (void)testApplyMultipleBackdropFilters {
649 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
651 flutter::TaskRunners runners(
self.name.UTF8String,
652 GetDefaultTaskRunner(),
653 GetDefaultTaskRunner(),
654 GetDefaultTaskRunner(),
655 GetDefaultTaskRunner());
658 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
659 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
662 flutterPlatformViewsController,
665 std::make_shared<fml::SyncSwitch>());
669 [flutterPlatformViewsController
671 withId:@"MockFlutterPlatformView"
675 [flutterPlatformViewsController
679 @"viewType" : @"MockFlutterPlatformView"
685 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
686 flutterPlatformViewsController.
flutterView = flutterView;
688 flutter::MutatorsStack stack;
690 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
691 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
692 stack.PushTransform(screenScaleMatrix);
694 for (
int i = 0; i < 50; i++) {
695 auto filter = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
696 stack.PushBackdropFilter(filter,
697 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
700 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
701 screenScaleMatrix, flutter::DlSize(20, 20), stack);
703 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
704 withParams:std::move(embeddedViewParams)];
705 [flutterPlatformViewsController
711 [flutterView addSubview:childClippingView];
713 [flutterView setNeedsLayout];
714 [flutterView layoutIfNeeded];
716 NSUInteger numberOfExpectedVisualEffectView = 0;
717 for (UIView* subview in childClippingView.subviews) {
718 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
721 XCTAssertLessThan(numberOfExpectedVisualEffectView, 50u);
722 if ([
self validateOneVisualEffectView:subview
723 expectedFrame:CGRectMake(0, 0, 10, 10)
724 inputRadius:(CGFloat)numberOfExpectedVisualEffectView]) {
725 numberOfExpectedVisualEffectView++;
728 XCTAssertEqual(numberOfExpectedVisualEffectView, (NSUInteger)numberOfExpectedVisualEffectView);
731 - (void)testAddBackdropFilters {
732 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
734 flutter::TaskRunners runners(
self.name.UTF8String,
735 GetDefaultTaskRunner(),
736 GetDefaultTaskRunner(),
737 GetDefaultTaskRunner(),
738 GetDefaultTaskRunner());
741 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
742 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
745 flutterPlatformViewsController,
748 std::make_shared<fml::SyncSwitch>());
752 [flutterPlatformViewsController
754 withId:@"MockFlutterPlatformView"
758 [flutterPlatformViewsController
762 @"viewType" : @"MockFlutterPlatformView"
768 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
769 flutterPlatformViewsController.
flutterView = flutterView;
771 flutter::MutatorsStack stack;
773 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
774 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
775 stack.PushTransform(screenScaleMatrix);
777 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
778 stack.PushBackdropFilter(filter,
779 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
781 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
782 screenScaleMatrix, flutter::DlSize(10, 10), stack);
784 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
785 withParams:std::move(embeddedViewParams)];
786 [flutterPlatformViewsController
792 [flutterView addSubview:childClippingView];
794 [flutterView setNeedsLayout];
795 [flutterView layoutIfNeeded];
797 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
798 for (UIView* subview in childClippingView.subviews) {
799 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
802 XCTAssertLessThan(originalVisualEffectViews.count, 1u);
803 if ([
self validateOneVisualEffectView:subview
804 expectedFrame:CGRectMake(0, 0, 10, 10)
805 inputRadius:(CGFloat)5]) {
806 [originalVisualEffectViews addObject:subview];
809 XCTAssertEqual(originalVisualEffectViews.count, 1u);
814 flutter::MutatorsStack stack2;
816 stack2.PushTransform(screenScaleMatrix);
818 for (
int i = 0; i < 2; i++) {
819 stack2.PushBackdropFilter(filter,
820 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
823 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
824 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
826 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
827 withParams:std::move(embeddedViewParams)];
828 [flutterPlatformViewsController
832 [flutterView setNeedsLayout];
833 [flutterView layoutIfNeeded];
835 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
836 for (UIView* subview in childClippingView.subviews) {
837 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
840 XCTAssertLessThan(newVisualEffectViews.count, 2u);
842 if ([
self validateOneVisualEffectView:subview
843 expectedFrame:CGRectMake(0, 0, 10, 10)
844 inputRadius:(CGFloat)5]) {
845 [newVisualEffectViews addObject:subview];
848 XCTAssertEqual(newVisualEffectViews.count, 2u);
849 for (NSUInteger i = 0; i < originalVisualEffectViews.count; i++) {
850 UIView* originalView = originalVisualEffectViews[i];
851 UIView* newView = newVisualEffectViews[i];
853 XCTAssertEqual(originalView, newView);
854 id mockOrignalView = OCMPartialMock(originalView);
855 OCMReject([mockOrignalView removeFromSuperview]);
856 [mockOrignalView stopMocking];
860 - (void)testRemoveBackdropFilters {
861 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
863 flutter::TaskRunners runners(
self.name.UTF8String,
864 GetDefaultTaskRunner(),
865 GetDefaultTaskRunner(),
866 GetDefaultTaskRunner(),
867 GetDefaultTaskRunner());
870 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
871 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
874 flutterPlatformViewsController,
877 std::make_shared<fml::SyncSwitch>());
881 [flutterPlatformViewsController
883 withId:@"MockFlutterPlatformView"
887 [flutterPlatformViewsController
891 @"viewType" : @"MockFlutterPlatformView"
897 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
898 flutterPlatformViewsController.
flutterView = flutterView;
900 flutter::MutatorsStack stack;
902 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
903 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
904 stack.PushTransform(screenScaleMatrix);
906 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
907 for (
int i = 0; i < 5; i++) {
908 stack.PushBackdropFilter(filter,
909 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
912 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
913 screenScaleMatrix, flutter::DlSize(10, 10), stack);
915 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
916 withParams:std::move(embeddedViewParams)];
917 [flutterPlatformViewsController
923 [flutterView addSubview:childClippingView];
925 [flutterView setNeedsLayout];
926 [flutterView layoutIfNeeded];
928 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
929 for (UIView* subview in childClippingView.subviews) {
930 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
933 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
934 if ([
self validateOneVisualEffectView:subview
935 expectedFrame:CGRectMake(0, 0, 10, 10)
936 inputRadius:(CGFloat)5]) {
937 [originalVisualEffectViews addObject:subview];
943 flutter::MutatorsStack stack2;
945 stack2.PushTransform(screenScaleMatrix);
947 for (
int i = 0; i < 4; i++) {
948 stack2.PushBackdropFilter(filter,
949 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
952 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
953 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
955 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
956 withParams:std::move(embeddedViewParams)];
957 [flutterPlatformViewsController
961 [flutterView setNeedsLayout];
962 [flutterView layoutIfNeeded];
964 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
965 for (UIView* subview in childClippingView.subviews) {
966 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
969 XCTAssertLessThan(newVisualEffectViews.count, 4u);
970 if ([
self validateOneVisualEffectView:subview
971 expectedFrame:CGRectMake(0, 0, 10, 10)
972 inputRadius:(CGFloat)5]) {
973 [newVisualEffectViews addObject:subview];
976 XCTAssertEqual(newVisualEffectViews.count, 4u);
978 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
979 UIView* newView = newVisualEffectViews[i];
980 id mockNewView = OCMPartialMock(newView);
981 UIView* originalView = originalVisualEffectViews[i];
983 XCTAssertEqual(originalView, newView);
984 OCMReject([mockNewView removeFromSuperview]);
985 [mockNewView stopMocking];
990 for (
int i = 0; i < 5; i++) {
995 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
996 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
998 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
999 withParams:std::move(embeddedViewParams)];
1000 [flutterPlatformViewsController
1004 [flutterView setNeedsLayout];
1005 [flutterView layoutIfNeeded];
1007 NSUInteger numberOfExpectedVisualEffectView = 0u;
1008 for (UIView* subview in childClippingView.subviews) {
1009 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1010 numberOfExpectedVisualEffectView++;
1013 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1016 - (void)testEditBackdropFilters {
1017 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1019 flutter::TaskRunners runners(
self.name.UTF8String,
1020 GetDefaultTaskRunner(),
1021 GetDefaultTaskRunner(),
1022 GetDefaultTaskRunner(),
1023 GetDefaultTaskRunner());
1026 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1027 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1030 flutterPlatformViewsController,
1033 std::make_shared<fml::SyncSwitch>());
1037 [flutterPlatformViewsController
1039 withId:@"MockFlutterPlatformView"
1043 [flutterPlatformViewsController
1047 @"viewType" : @"MockFlutterPlatformView"
1053 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1054 flutterPlatformViewsController.
flutterView = flutterView;
1056 flutter::MutatorsStack stack;
1058 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1059 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1060 stack.PushTransform(screenScaleMatrix);
1062 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1063 for (
int i = 0; i < 5; i++) {
1064 stack.PushBackdropFilter(filter,
1065 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1068 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1069 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1071 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1072 withParams:std::move(embeddedViewParams)];
1073 [flutterPlatformViewsController
1079 [flutterView addSubview:childClippingView];
1081 [flutterView setNeedsLayout];
1082 [flutterView layoutIfNeeded];
1084 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
1085 for (UIView* subview in childClippingView.subviews) {
1086 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1089 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
1090 if ([
self validateOneVisualEffectView:subview
1091 expectedFrame:CGRectMake(0, 0, 10, 10)
1092 inputRadius:(CGFloat)5]) {
1093 [originalVisualEffectViews addObject:subview];
1099 flutter::MutatorsStack stack2;
1101 stack2.PushTransform(screenScaleMatrix);
1103 for (
int i = 0; i < 5; i++) {
1105 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1107 stack2.PushBackdropFilter(
1108 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1112 stack2.PushBackdropFilter(filter,
1113 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1116 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1117 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1119 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1120 withParams:std::move(embeddedViewParams)];
1121 [flutterPlatformViewsController
1125 [flutterView setNeedsLayout];
1126 [flutterView layoutIfNeeded];
1128 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
1129 for (UIView* subview in childClippingView.subviews) {
1130 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1133 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1134 CGFloat expectInputRadius = 5;
1135 if (newVisualEffectViews.count == 3) {
1136 expectInputRadius = 2;
1138 if ([
self validateOneVisualEffectView:subview
1139 expectedFrame:CGRectMake(0, 0, 10, 10)
1140 inputRadius:expectInputRadius]) {
1141 [newVisualEffectViews addObject:subview];
1144 XCTAssertEqual(newVisualEffectViews.count, 5u);
1145 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1146 UIView* newView = newVisualEffectViews[i];
1147 id mockNewView = OCMPartialMock(newView);
1148 UIView* originalView = originalVisualEffectViews[i];
1150 XCTAssertEqual(originalView, newView);
1151 OCMReject([mockNewView removeFromSuperview]);
1152 [mockNewView stopMocking];
1154 [newVisualEffectViews removeAllObjects];
1158 for (
int i = 0; i < 5; i++) {
1162 for (
int i = 0; i < 5; i++) {
1164 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1165 stack2.PushBackdropFilter(
1166 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1170 stack2.PushBackdropFilter(filter,
1171 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1174 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1175 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1177 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1178 withParams:std::move(embeddedViewParams)];
1179 [flutterPlatformViewsController
1183 [flutterView setNeedsLayout];
1184 [flutterView layoutIfNeeded];
1186 for (UIView* subview in childClippingView.subviews) {
1187 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1190 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1191 CGFloat expectInputRadius = 5;
1192 if (newVisualEffectViews.count == 0) {
1193 expectInputRadius = 2;
1195 if ([
self validateOneVisualEffectView:subview
1196 expectedFrame:CGRectMake(0, 0, 10, 10)
1197 inputRadius:expectInputRadius]) {
1198 [newVisualEffectViews addObject:subview];
1201 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1202 UIView* newView = newVisualEffectViews[i];
1203 id mockNewView = OCMPartialMock(newView);
1204 UIView* originalView = originalVisualEffectViews[i];
1206 XCTAssertEqual(originalView, newView);
1207 OCMReject([mockNewView removeFromSuperview]);
1208 [mockNewView stopMocking];
1210 [newVisualEffectViews removeAllObjects];
1214 for (
int i = 0; i < 5; i++) {
1218 for (
int i = 0; i < 5; i++) {
1220 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1221 stack2.PushBackdropFilter(
1222 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1226 stack2.PushBackdropFilter(filter,
1227 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1230 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1231 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1233 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1234 withParams:std::move(embeddedViewParams)];
1235 [flutterPlatformViewsController
1239 [flutterView setNeedsLayout];
1240 [flutterView layoutIfNeeded];
1242 for (UIView* subview in childClippingView.subviews) {
1243 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1246 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1247 CGFloat expectInputRadius = 5;
1248 if (newVisualEffectViews.count == 4) {
1249 expectInputRadius = 2;
1251 if ([
self validateOneVisualEffectView:subview
1252 expectedFrame:CGRectMake(0, 0, 10, 10)
1253 inputRadius:expectInputRadius]) {
1254 [newVisualEffectViews addObject:subview];
1257 XCTAssertEqual(newVisualEffectViews.count, 5u);
1259 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1260 UIView* newView = newVisualEffectViews[i];
1261 id mockNewView = OCMPartialMock(newView);
1262 UIView* originalView = originalVisualEffectViews[i];
1264 XCTAssertEqual(originalView, newView);
1265 OCMReject([mockNewView removeFromSuperview]);
1266 [mockNewView stopMocking];
1268 [newVisualEffectViews removeAllObjects];
1272 for (
int i = 0; i < 5; i++) {
1276 for (
int i = 0; i < 5; i++) {
1277 auto filter2 = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
1279 stack2.PushBackdropFilter(filter2,
1280 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1283 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1284 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1286 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1287 withParams:std::move(embeddedViewParams)];
1288 [flutterPlatformViewsController
1292 [flutterView setNeedsLayout];
1293 [flutterView layoutIfNeeded];
1295 for (UIView* subview in childClippingView.subviews) {
1296 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1299 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1300 if ([
self validateOneVisualEffectView:subview
1301 expectedFrame:CGRectMake(0, 0, 10, 10)
1302 inputRadius:(CGFloat)newVisualEffectViews.count]) {
1303 [newVisualEffectViews addObject:subview];
1306 XCTAssertEqual(newVisualEffectViews.count, 5u);
1308 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1309 UIView* newView = newVisualEffectViews[i];
1310 id mockNewView = OCMPartialMock(newView);
1311 UIView* originalView = originalVisualEffectViews[i];
1313 XCTAssertEqual(originalView, newView);
1314 OCMReject([mockNewView removeFromSuperview]);
1315 [mockNewView stopMocking];
1317 [newVisualEffectViews removeAllObjects];
1320 - (void)testApplyBackdropFilterNotDlBlurImageFilter {
1321 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1323 flutter::TaskRunners runners(
self.name.UTF8String,
1324 GetDefaultTaskRunner(),
1325 GetDefaultTaskRunner(),
1326 GetDefaultTaskRunner(),
1327 GetDefaultTaskRunner());
1330 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1331 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1334 flutterPlatformViewsController,
1337 std::make_shared<fml::SyncSwitch>());
1341 [flutterPlatformViewsController
1343 withId:@"MockFlutterPlatformView"
1347 [flutterPlatformViewsController
1351 @"viewType" : @"MockFlutterPlatformView"
1357 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1358 flutterPlatformViewsController.
flutterView = flutterView;
1360 flutter::MutatorsStack stack;
1362 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1363 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1364 stack.PushTransform(screenScaleMatrix);
1366 auto dilateFilter = flutter::DlDilateImageFilter::Make(5, 2);
1367 stack.PushBackdropFilter(dilateFilter, flutter::DlRect());
1369 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1370 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1372 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1373 withParams:std::move(embeddedViewParams)];
1374 [flutterPlatformViewsController
1381 [flutterView addSubview:childClippingView];
1383 [flutterView setNeedsLayout];
1384 [flutterView layoutIfNeeded];
1386 NSUInteger numberOfExpectedVisualEffectView = 0;
1387 for (UIView* subview in childClippingView.subviews) {
1388 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1389 numberOfExpectedVisualEffectView++;
1392 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1396 flutter::MutatorsStack stack2;
1398 stack2.PushTransform(screenScaleMatrix);
1400 auto blurFilter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1402 for (
int i = 0; i < 5; i++) {
1404 stack2.PushBackdropFilter(
1405 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1409 stack2.PushBackdropFilter(blurFilter,
1410 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1413 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1414 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1416 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1417 withParams:std::move(embeddedViewParams)];
1418 [flutterPlatformViewsController
1422 [flutterView setNeedsLayout];
1423 [flutterView layoutIfNeeded];
1425 numberOfExpectedVisualEffectView = 0;
1426 for (UIView* subview in childClippingView.subviews) {
1427 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1430 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1431 if ([
self validateOneVisualEffectView:subview
1432 expectedFrame:CGRectMake(0, 0, 10, 10)
1433 inputRadius:(CGFloat)5]) {
1434 numberOfExpectedVisualEffectView++;
1437 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1441 for (
int i = 0; i < 5; i++) {
1445 for (
int i = 0; i < 5; i++) {
1447 stack2.PushBackdropFilter(
1448 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1452 stack2.PushBackdropFilter(blurFilter,
1453 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1456 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1457 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1459 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1460 withParams:std::move(embeddedViewParams)];
1461 [flutterPlatformViewsController
1465 [flutterView setNeedsLayout];
1466 [flutterView layoutIfNeeded];
1468 numberOfExpectedVisualEffectView = 0;
1469 for (UIView* subview in childClippingView.subviews) {
1470 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1473 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1474 if ([
self validateOneVisualEffectView:subview
1475 expectedFrame:CGRectMake(0, 0, 10, 10)
1476 inputRadius:(CGFloat)5]) {
1477 numberOfExpectedVisualEffectView++;
1480 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1484 for (
int i = 0; i < 5; i++) {
1488 for (
int i = 0; i < 5; i++) {
1490 stack2.PushBackdropFilter(
1491 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1495 stack2.PushBackdropFilter(blurFilter,
1496 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1499 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1500 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1502 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1503 withParams:std::move(embeddedViewParams)];
1504 [flutterPlatformViewsController
1508 [flutterView setNeedsLayout];
1509 [flutterView layoutIfNeeded];
1511 numberOfExpectedVisualEffectView = 0;
1512 for (UIView* subview in childClippingView.subviews) {
1513 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1516 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1517 if ([
self validateOneVisualEffectView:subview
1518 expectedFrame:CGRectMake(0, 0, 10, 10)
1519 inputRadius:(CGFloat)5]) {
1520 numberOfExpectedVisualEffectView++;
1523 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1527 for (
int i = 0; i < 5; i++) {
1531 for (
int i = 0; i < 5; i++) {
1532 stack2.PushBackdropFilter(dilateFilter,
1533 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1536 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1537 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1539 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1540 withParams:std::move(embeddedViewParams)];
1541 [flutterPlatformViewsController
1545 [flutterView setNeedsLayout];
1546 [flutterView layoutIfNeeded];
1548 numberOfExpectedVisualEffectView = 0;
1549 for (UIView* subview in childClippingView.subviews) {
1550 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1551 numberOfExpectedVisualEffectView++;
1554 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1557 - (void)testApplyBackdropFilterCorrectAPI {
1562 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1563 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1568 visualEffectView:visualEffectView];
1569 XCTAssertNotNil(platformViewFilter);
1572 - (void)testApplyBackdropFilterAPIChangedInvalidUIVisualEffectView {
1574 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] init];
1579 visualEffectView:visualEffectView];
1580 XCTAssertNil(platformViewFilter);
1583 - (void)testApplyBackdropFilterAPIChangedNoGaussianBlurFilter {
1585 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1586 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1587 NSArray* subviews = editedUIVisualEffectView.subviews;
1588 for (UIView* view in subviews) {
1589 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1590 for (CIFilter* filter in view.layer.filters) {
1591 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1592 [filter setValue:@"notGaussianBlur" forKey:@"name"];
1603 visualEffectView:editedUIVisualEffectView];
1604 XCTAssertNil(platformViewFilter);
1607 - (void)testApplyBackdropFilterAPIChangedInvalidInputRadius {
1609 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1610 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1611 NSArray* subviews = editedUIVisualEffectView.subviews;
1612 for (UIView* view in subviews) {
1613 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1614 for (CIFilter* filter in view.layer.filters) {
1615 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1616 [filter setValue:@"invalidInputRadius" forKey:@"inputRadius"];
1628 visualEffectView:editedUIVisualEffectView];
1629 XCTAssertNil(platformViewFilter);
1632 - (void)testApplyBackdropFilterRespectsClipRRect {
1633 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1635 flutter::TaskRunners runners(
self.name.UTF8String,
1636 GetDefaultTaskRunner(),
1637 GetDefaultTaskRunner(),
1638 GetDefaultTaskRunner(),
1639 GetDefaultTaskRunner());
1642 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1643 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1646 flutterPlatformViewsController,
1649 std::make_shared<fml::SyncSwitch>());
1653 [flutterPlatformViewsController
1655 withId:@"MockFlutterPlatformView"
1659 [flutterPlatformViewsController
1663 @"viewType" : @"MockFlutterPlatformView"
1669 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1670 flutterPlatformViewsController.
flutterView = flutterView;
1672 flutter::MutatorsStack stack;
1674 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1675 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1676 stack.PushTransform(screenScaleMatrix);
1679 auto clipRect = flutter::DlRect::MakeXYWH(2, 2, 6, 6);
1680 auto clipRRect = flutter::DlRoundRect::MakeRectXY(clipRect, 3, 3);
1681 stack.PushPlatformViewClipRRect(clipRRect);
1684 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1685 stack.PushBackdropFilter(filter,
1686 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1688 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1689 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1691 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1692 withParams:std::move(embeddedViewParams)];
1693 [flutterPlatformViewsController
1699 [flutterView addSubview:childClippingView];
1701 [flutterView setNeedsLayout];
1702 [flutterView layoutIfNeeded];
1705 XCTAssertEqual(filters.count, 1u);
1707 UIVisualEffectView* visualEffectView = filters[0];
1708 auto radii = clipRRect.GetRadii();
1710 XCTAssertEqual(visualEffectView.layer.cornerRadius, radii.top_left.width);
1713 - (void)testBackdropFilterVisualEffectSubviewBackgroundColor {
1714 __weak UIVisualEffectView* weakVisualEffectView;
1717 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1718 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1719 weakVisualEffectView = visualEffectView;
1724 visualEffectView:visualEffectView];
1725 CGColorRef visualEffectSubviewBackgroundColor = nil;
1726 for (UIView* view in [platformViewFilter backdropFilterView].subviews) {
1727 if ([NSStringFromClass([view
class]) hasSuffix:
@"VisualEffectSubview"]) {
1728 visualEffectSubviewBackgroundColor = view.layer.backgroundColor;
1732 CGColorEqualToColor(visualEffectSubviewBackgroundColor, UIColor.clearColor.CGColor));
1734 XCTAssertNil(weakVisualEffectView);
1737 - (void)testCompositePlatformView {
1738 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1740 flutter::TaskRunners runners(
self.name.UTF8String,
1741 GetDefaultTaskRunner(),
1742 GetDefaultTaskRunner(),
1743 GetDefaultTaskRunner(),
1744 GetDefaultTaskRunner());
1747 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1748 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1751 flutterPlatformViewsController,
1754 std::make_shared<fml::SyncSwitch>());
1758 [flutterPlatformViewsController
1760 withId:@"MockFlutterPlatformView"
1764 [flutterPlatformViewsController
1768 @"viewType" : @"MockFlutterPlatformView"
1774 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1775 flutterPlatformViewsController.
flutterView = flutterView;
1777 flutter::MutatorsStack stack;
1779 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1780 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1781 stack.PushTransform(screenScaleMatrix);
1783 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
1784 stack.PushTransform(translateMatrix);
1785 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
1787 auto embeddedViewParams =
1788 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
1790 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1791 withParams:std::move(embeddedViewParams)];
1792 [flutterPlatformViewsController
1796 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1797 toView:flutterView];
1798 XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
1801 - (void)testBackdropFilterCorrectlyPushedAndReset {
1802 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1804 flutter::TaskRunners runners(
self.name.UTF8String,
1805 GetDefaultTaskRunner(),
1806 GetDefaultTaskRunner(),
1807 GetDefaultTaskRunner(),
1808 GetDefaultTaskRunner());
1811 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1812 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1815 flutterPlatformViewsController,
1818 std::make_shared<fml::SyncSwitch>());
1822 [flutterPlatformViewsController
1824 withId:@"MockFlutterPlatformView"
1828 [flutterPlatformViewsController
1832 @"viewType" : @"MockFlutterPlatformView"
1838 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1839 flutterPlatformViewsController.
flutterView = flutterView;
1841 flutter::MutatorsStack stack;
1843 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1844 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1845 stack.PushTransform(screenScaleMatrix);
1847 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1848 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1850 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1851 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1852 withParams:std::move(embeddedViewParams)];
1854 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp, std::nullopt);
1855 [flutterPlatformViewsController
1856 pushFilterToVisitedPlatformViews:filter
1857 withRect:flutter::DlRect::MakeXYWH(0, 0, screenScale * 10,
1859 [flutterPlatformViewsController
1865 [flutterView addSubview:childClippingView];
1867 [flutterView setNeedsLayout];
1868 [flutterView layoutIfNeeded];
1871 NSUInteger numberOfExpectedVisualEffectView = 0;
1872 for (UIView* subview in childClippingView.subviews) {
1873 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1876 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
1877 if ([
self validateOneVisualEffectView:subview
1878 expectedFrame:CGRectMake(0, 0, 10, 10)
1880 numberOfExpectedVisualEffectView++;
1883 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
1886 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
1887 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1888 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1889 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1890 withParams:std::move(embeddedViewParams2)];
1891 [flutterPlatformViewsController
1897 [flutterView setNeedsLayout];
1898 [flutterView layoutIfNeeded];
1900 numberOfExpectedVisualEffectView = 0;
1901 for (UIView* subview in childClippingView.subviews) {
1902 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1905 numberOfExpectedVisualEffectView++;
1907 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1910 - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
1911 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1913 flutter::TaskRunners runners(
self.name.UTF8String,
1914 GetDefaultTaskRunner(),
1915 GetDefaultTaskRunner(),
1916 GetDefaultTaskRunner(),
1917 GetDefaultTaskRunner());
1920 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1921 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1924 flutterPlatformViewsController,
1927 std::make_shared<fml::SyncSwitch>());
1931 [flutterPlatformViewsController
1933 withId:@"MockFlutterPlatformView"
1937 [flutterPlatformViewsController
1941 @"viewType" : @"MockFlutterPlatformView"
1947 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1948 flutterPlatformViewsController.
flutterView = flutterView;
1950 flutter::MutatorsStack stack;
1952 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1953 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1954 stack.PushTransform(screenScaleMatrix);
1956 flutter::DlMatrix rotateMatrix = flutter::DlMatrix::MakeRotationZ(flutter::DlDegrees(10));
1957 stack.PushTransform(rotateMatrix);
1958 flutter::DlMatrix finalMatrix = screenScaleMatrix * rotateMatrix;
1960 auto embeddedViewParams =
1961 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
1963 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1964 withParams:std::move(embeddedViewParams)];
1965 [flutterPlatformViewsController
1969 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1970 toView:flutterView];
1976 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
1978 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
1981 fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width),
1984 fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
1988 - (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView {
1989 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1991 flutter::TaskRunners runners(
self.name.UTF8String,
1992 GetDefaultTaskRunner(),
1993 GetDefaultTaskRunner(),
1994 GetDefaultTaskRunner(),
1995 GetDefaultTaskRunner());
1998 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1999 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2002 flutterPlatformViewsController,
2005 std::make_shared<fml::SyncSwitch>());
2009 [flutterPlatformViewsController
2011 withId:@"MockFlutterPlatformView"
2015 [flutterPlatformViewsController
2019 @"viewType" : @"MockFlutterPlatformView"
2025 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2026 flutterPlatformViewsController.
flutterView = flutterView;
2028 flutter::MutatorsStack stack;
2030 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2031 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2032 stack.PushTransform(screenScaleMatrix);
2033 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2035 stack.PushTransform(translateMatrix);
2037 flutter::DlRect rect = flutter::DlRect::MakeXYWH(0, 0, 25, 25);
2038 stack.PushClipRect(rect);
2041 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(-1, -1, 25, 25);
2042 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2043 stack.PushClipRRect(rrect);
2045 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2046 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
2048 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2049 withParams:std::move(embeddedViewParams)];
2050 [flutterPlatformViewsController
2057 [flutterView addSubview:childClippingView];
2059 [flutterView setNeedsLayout];
2060 [flutterView layoutIfNeeded];
2061 XCTAssertNil(childClippingView.maskView);
2064 - (void)testClipRRectOnlyHasCornersInterceptWithPlatformViewShouldAddMaskView {
2065 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2067 flutter::TaskRunners runners(
self.name.UTF8String,
2068 GetDefaultTaskRunner(),
2069 GetDefaultTaskRunner(),
2070 GetDefaultTaskRunner(),
2071 GetDefaultTaskRunner());
2074 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2075 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2078 flutterPlatformViewsController,
2081 std::make_shared<fml::SyncSwitch>());
2085 [flutterPlatformViewsController
2087 withId:@"MockFlutterPlatformView"
2091 [flutterPlatformViewsController
2095 @"viewType" : @"MockFlutterPlatformView"
2101 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2102 flutterPlatformViewsController.
flutterView = flutterView;
2104 flutter::MutatorsStack stack;
2106 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2107 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2108 stack.PushTransform(screenScaleMatrix);
2109 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2111 stack.PushTransform(translateMatrix);
2115 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(0, 0, 10, 10);
2116 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2117 stack.PushClipRRect(rrect);
2119 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2120 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
2122 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2123 withParams:std::move(embeddedViewParams)];
2124 [flutterPlatformViewsController
2131 [flutterView addSubview:childClippingView];
2133 [flutterView setNeedsLayout];
2134 [flutterView layoutIfNeeded];
2136 XCTAssertNotNil(childClippingView.maskView);
2139 - (void)testClipRect {
2140 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2142 flutter::TaskRunners runners(
self.name.UTF8String,
2143 GetDefaultTaskRunner(),
2144 GetDefaultTaskRunner(),
2145 GetDefaultTaskRunner(),
2146 GetDefaultTaskRunner());
2149 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2150 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2153 flutterPlatformViewsController,
2156 std::make_shared<fml::SyncSwitch>());
2160 [flutterPlatformViewsController
2162 withId:@"MockFlutterPlatformView"
2166 [flutterPlatformViewsController
2170 @"viewType" : @"MockFlutterPlatformView"
2176 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2177 flutterPlatformViewsController.
flutterView = flutterView;
2179 flutter::MutatorsStack stack;
2181 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2182 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2183 stack.PushTransform(screenScaleMatrix);
2185 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2186 stack.PushClipRect(rect);
2188 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2189 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2191 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2192 withParams:std::move(embeddedViewParams)];
2193 [flutterPlatformViewsController
2200 [flutterView addSubview:childClippingView];
2202 [flutterView setNeedsLayout];
2203 [flutterView layoutIfNeeded];
2205 CGRect insideClipping = CGRectMake(2, 2, 3, 3);
2206 for (
int i = 0; i < 10; i++) {
2207 for (
int j = 0; j < 10; j++) {
2208 CGPoint point = CGPointMake(i, j);
2209 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2210 if (CGRectContainsPoint(insideClipping, point)) {
2211 XCTAssertEqual(alpha, 255);
2213 XCTAssertEqual(alpha, 0);
2219 - (void)testClipRect_multipleClips {
2220 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2222 flutter::TaskRunners runners(
self.name.UTF8String,
2223 GetDefaultTaskRunner(),
2224 GetDefaultTaskRunner(),
2225 GetDefaultTaskRunner(),
2226 GetDefaultTaskRunner());
2229 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2230 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2233 flutterPlatformViewsController,
2236 std::make_shared<fml::SyncSwitch>());
2240 [flutterPlatformViewsController
2242 withId:@"MockFlutterPlatformView"
2246 [flutterPlatformViewsController
2250 @"viewType" : @"MockFlutterPlatformView"
2256 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2257 flutterPlatformViewsController.
flutterView = flutterView;
2259 flutter::MutatorsStack stack;
2261 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2262 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2263 stack.PushTransform(screenScaleMatrix);
2265 flutter::DlRect rect1 = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2266 stack.PushClipRect(rect1);
2268 flutter::DlRect rect2 = flutter::DlRect::MakeXYWH(3, 3, 3, 3);
2269 stack.PushClipRect(rect2);
2271 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2272 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2274 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2275 withParams:std::move(embeddedViewParams)];
2276 [flutterPlatformViewsController
2283 [flutterView addSubview:childClippingView];
2285 [flutterView setNeedsLayout];
2286 [flutterView layoutIfNeeded];
2305 CGRect insideClipping = CGRectMake(3, 3, 2, 2);
2306 for (
int i = 0; i < 10; i++) {
2307 for (
int j = 0; j < 10; j++) {
2308 CGPoint point = CGPointMake(i, j);
2309 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2310 if (CGRectContainsPoint(insideClipping, point)) {
2311 XCTAssertEqual(alpha, 255);
2313 XCTAssertEqual(alpha, 0);
2319 - (void)testClipRRect {
2320 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2322 flutter::TaskRunners runners(
self.name.UTF8String,
2323 GetDefaultTaskRunner(),
2324 GetDefaultTaskRunner(),
2325 GetDefaultTaskRunner(),
2326 GetDefaultTaskRunner());
2329 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2330 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2333 flutterPlatformViewsController,
2336 std::make_shared<fml::SyncSwitch>());
2340 [flutterPlatformViewsController
2342 withId:@"MockFlutterPlatformView"
2346 [flutterPlatformViewsController
2350 @"viewType" : @"MockFlutterPlatformView"
2356 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2357 flutterPlatformViewsController.
flutterView = flutterView;
2359 flutter::MutatorsStack stack;
2361 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2362 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2363 stack.PushTransform(screenScaleMatrix);
2365 flutter::DlRoundRect rrect =
2366 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2367 stack.PushClipRRect(rrect);
2369 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2370 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2372 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2373 withParams:std::move(embeddedViewParams)];
2374 [flutterPlatformViewsController
2381 [flutterView addSubview:childClippingView];
2383 [flutterView setNeedsLayout];
2384 [flutterView layoutIfNeeded];
2405 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2406 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2407 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2408 for (
int i = 0; i < 10; i++) {
2409 for (
int j = 0; j < 10; j++) {
2410 CGPoint point = CGPointMake(i, j);
2411 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2412 if (CGRectContainsPoint(innerClipping1, point) ||
2413 CGRectContainsPoint(innerClipping2, point)) {
2415 XCTAssertEqual(alpha, 255);
2416 }
else if (CGRectContainsPoint(outterClipping, point)) {
2418 XCTAssert(0 < alpha && alpha < 255);
2421 XCTAssertEqual(alpha, 0);
2427 - (void)testClipRRect_multipleClips {
2428 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2430 flutter::TaskRunners runners(
self.name.UTF8String,
2431 GetDefaultTaskRunner(),
2432 GetDefaultTaskRunner(),
2433 GetDefaultTaskRunner(),
2434 GetDefaultTaskRunner());
2437 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2438 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2441 flutterPlatformViewsController,
2444 std::make_shared<fml::SyncSwitch>());
2448 [flutterPlatformViewsController
2450 withId:@"MockFlutterPlatformView"
2454 [flutterPlatformViewsController
2458 @"viewType" : @"MockFlutterPlatformView"
2464 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2465 flutterPlatformViewsController.
flutterView = flutterView;
2467 flutter::MutatorsStack stack;
2469 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2470 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2471 stack.PushTransform(screenScaleMatrix);
2473 flutter::DlRoundRect rrect =
2474 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2475 stack.PushClipRRect(rrect);
2477 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2478 stack.PushClipRect(rect);
2480 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2481 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2483 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2484 withParams:std::move(embeddedViewParams)];
2485 [flutterPlatformViewsController
2492 [flutterView addSubview:childClippingView];
2494 [flutterView setNeedsLayout];
2495 [flutterView layoutIfNeeded];
2516 CGRect clipping = CGRectMake(4, 2, 4, 6);
2517 for (
int i = 0; i < 10; i++) {
2518 for (
int j = 0; j < 10; j++) {
2519 CGPoint point = CGPointMake(i, j);
2520 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2521 if (i == 7 && (j == 2 || j == 7)) {
2523 XCTAssert(0 < alpha && alpha < 255);
2526 (i == 4 && j >= 2 && j <= 7) ||
2528 (i == 7 && j >= 2 && j <= 7) ||
2530 (j == 2 && i >= 4 && i <= 7) ||
2532 (j == 7 && i >= 4 && i <= 7)) {
2535 XCTAssert(alpha > 127);
2536 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2537 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2540 XCTAssert(alpha < 127);
2541 }
else if (CGRectContainsPoint(clipping, point)) {
2543 XCTAssertEqual(alpha, 255);
2546 XCTAssertEqual(alpha, 0);
2552 - (void)testClipPath {
2553 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2555 flutter::TaskRunners runners(
self.name.UTF8String,
2556 GetDefaultTaskRunner(),
2557 GetDefaultTaskRunner(),
2558 GetDefaultTaskRunner(),
2559 GetDefaultTaskRunner());
2562 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2563 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2566 flutterPlatformViewsController,
2569 std::make_shared<fml::SyncSwitch>());
2573 [flutterPlatformViewsController
2575 withId:@"MockFlutterPlatformView"
2579 [flutterPlatformViewsController
2583 @"viewType" : @"MockFlutterPlatformView"
2589 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2590 flutterPlatformViewsController.
flutterView = flutterView;
2592 flutter::MutatorsStack stack;
2594 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2595 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2596 stack.PushTransform(screenScaleMatrix);
2598 flutter::DlPath path =
2599 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2600 stack.PushClipPath(path);
2602 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2603 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2605 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2606 withParams:std::move(embeddedViewParams)];
2607 [flutterPlatformViewsController
2614 [flutterView addSubview:childClippingView];
2616 [flutterView setNeedsLayout];
2617 [flutterView layoutIfNeeded];
2638 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2639 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2640 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2641 for (
int i = 0; i < 10; i++) {
2642 for (
int j = 0; j < 10; j++) {
2643 CGPoint point = CGPointMake(i, j);
2644 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2645 if (CGRectContainsPoint(innerClipping1, point) ||
2646 CGRectContainsPoint(innerClipping2, point)) {
2648 XCTAssertEqual(alpha, 255);
2649 }
else if (CGRectContainsPoint(outterClipping, point)) {
2651 XCTAssert(0 < alpha && alpha < 255);
2654 XCTAssertEqual(alpha, 0);
2660 - (void)testClipPath_multipleClips {
2661 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2663 flutter::TaskRunners runners(
self.name.UTF8String,
2664 GetDefaultTaskRunner(),
2665 GetDefaultTaskRunner(),
2666 GetDefaultTaskRunner(),
2667 GetDefaultTaskRunner());
2670 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2671 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2674 flutterPlatformViewsController,
2677 std::make_shared<fml::SyncSwitch>());
2681 [flutterPlatformViewsController
2683 withId:@"MockFlutterPlatformView"
2687 [flutterPlatformViewsController
2691 @"viewType" : @"MockFlutterPlatformView"
2697 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2698 flutterPlatformViewsController.
flutterView = flutterView;
2700 flutter::MutatorsStack stack;
2702 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2703 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2704 stack.PushTransform(screenScaleMatrix);
2706 flutter::DlPath path =
2707 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2708 stack.PushClipPath(path);
2710 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2711 stack.PushClipRect(rect);
2713 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2714 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2716 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2717 withParams:std::move(embeddedViewParams)];
2718 [flutterPlatformViewsController
2725 [flutterView addSubview:childClippingView];
2727 [flutterView setNeedsLayout];
2728 [flutterView layoutIfNeeded];
2749 CGRect clipping = CGRectMake(4, 2, 4, 6);
2750 for (
int i = 0; i < 10; i++) {
2751 for (
int j = 0; j < 10; j++) {
2752 CGPoint point = CGPointMake(i, j);
2753 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2754 if (i == 7 && (j == 2 || j == 7)) {
2756 XCTAssert(0 < alpha && alpha < 255);
2759 (i == 4 && j >= 2 && j <= 7) ||
2761 (i == 7 && j >= 2 && j <= 7) ||
2763 (j == 2 && i >= 4 && i <= 7) ||
2765 (j == 7 && i >= 4 && i <= 7)) {
2768 XCTAssert(alpha > 127);
2769 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2770 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2773 XCTAssert(alpha < 127);
2774 }
else if (CGRectContainsPoint(clipping, point)) {
2776 XCTAssertEqual(alpha, 255);
2779 XCTAssertEqual(alpha, 0);
2785 - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
2786 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2788 flutter::TaskRunners runners(
self.name.UTF8String,
2789 GetDefaultTaskRunner(),
2790 GetDefaultTaskRunner(),
2791 GetDefaultTaskRunner(),
2792 GetDefaultTaskRunner());
2795 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2796 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2799 flutterPlatformViewsController,
2802 std::make_shared<fml::SyncSwitch>());
2806 [flutterPlatformViewsController
2808 withId:@"MockFlutterPlatformView"
2812 [flutterPlatformViewsController
2816 @"viewType" : @"MockFlutterPlatformView"
2824 while (touchInteceptorView != nil &&
2826 touchInteceptorView = touchInteceptorView.superview;
2828 XCTAssertNotNil(touchInteceptorView);
2831 UIGestureRecognizer* forwardGectureRecognizer = nil;
2832 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2834 forwardGectureRecognizer = gestureRecognizer;
2840 NSSet* touches1 = [[NSSet alloc] init];
2841 id event1 = OCMClassMock([UIEvent
class]);
2843 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2844 OCMReject([flutterViewController touchesBegan:touches1 withEvent:event1]);
2847 NSSet* touches2 = [[NSSet alloc] init];
2848 id event2 = OCMClassMock([UIEvent
class]);
2850 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
2851 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
2854 - (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled {
2855 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2857 flutter::TaskRunners runners(
self.name.UTF8String,
2858 GetDefaultTaskRunner(),
2859 GetDefaultTaskRunner(),
2860 GetDefaultTaskRunner(),
2861 GetDefaultTaskRunner());
2864 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2865 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2868 flutterPlatformViewsController,
2871 std::make_shared<fml::SyncSwitch>());
2875 [flutterPlatformViewsController
2877 withId:@"MockFlutterPlatformView"
2881 [flutterPlatformViewsController
2885 @"viewType" : @"MockFlutterPlatformView"
2893 while (touchInteceptorView != nil &&
2895 touchInteceptorView = touchInteceptorView.superview;
2897 XCTAssertNotNil(touchInteceptorView);
2900 UIGestureRecognizer* forwardGectureRecognizer = nil;
2901 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2903 forwardGectureRecognizer = gestureRecognizer;
2912 NSSet* touches1 = [[NSSet alloc] init];
2913 id event1 = OCMClassMock([UIEvent
class]);
2914 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2915 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2920 NSSet* touches2 = [[NSSet alloc] init];
2921 id event2 = OCMClassMock([UIEvent
class]);
2922 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2923 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2925 NSSet* touches3 = [[NSSet alloc] init];
2926 id event3 = OCMClassMock([UIEvent
class]);
2927 [forwardGectureRecognizer touchesEnded:touches3 withEvent:event3];
2928 OCMVerify([flutterViewController touchesEnded:touches3 withEvent:event3]);
2931 NSSet* touches4 = [[NSSet alloc] init];
2932 id event4 = OCMClassMock([UIEvent
class]);
2933 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2934 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2936 NSSet* touches5 = [[NSSet alloc] init];
2937 id event5 = OCMClassMock([UIEvent
class]);
2938 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2939 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2946 NSSet* touches1 = [[NSSet alloc] init];
2947 id event1 = OCMClassMock([UIEvent
class]);
2948 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2949 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2954 NSSet* touches2 = [[NSSet alloc] init];
2955 id event2 = OCMClassMock([UIEvent
class]);
2956 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2957 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2959 NSSet* touches3 = [[NSSet alloc] init];
2960 id event3 = OCMClassMock([UIEvent
class]);
2961 [forwardGectureRecognizer touchesCancelled:touches3 withEvent:event3];
2962 OCMVerify([flutterViewController forceTouchesCancelled:touches3]);
2965 NSSet* touches4 = [[NSSet alloc] init];
2966 id event4 = OCMClassMock([UIEvent
class]);
2967 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2968 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2970 NSSet* touches5 = [[NSSet alloc] init];
2971 id event5 = OCMClassMock([UIEvent
class]);
2972 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2973 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2976 [flutterPlatformViewsController
reset];
2980 testSetFlutterViewControllerInTheMiddleOfTouchEventAllowsTheNewControllerToHandleSecondTouchSequence {
2981 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2983 flutter::TaskRunners runners(
self.name.UTF8String,
2984 GetDefaultTaskRunner(),
2985 GetDefaultTaskRunner(),
2986 GetDefaultTaskRunner(),
2987 GetDefaultTaskRunner());
2990 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2991 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2994 flutterPlatformViewsController,
2997 std::make_shared<fml::SyncSwitch>());
3001 [flutterPlatformViewsController
3003 withId:@"MockFlutterPlatformView"
3007 [flutterPlatformViewsController
3011 @"viewType" : @"MockFlutterPlatformView"
3019 while (touchInteceptorView != nil &&
3021 touchInteceptorView = touchInteceptorView.superview;
3023 XCTAssertNotNil(touchInteceptorView);
3026 UIGestureRecognizer* forwardGectureRecognizer = nil;
3027 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3029 forwardGectureRecognizer = gestureRecognizer;
3037 NSSet* touches1 = [NSSet setWithObject:@1];
3038 id event1 = OCMClassMock([UIEvent
class]);
3039 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3040 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
3047 NSSet* touches2 = [NSSet setWithObject:@1];
3048 id event2 = OCMClassMock([UIEvent
class]);
3049 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
3050 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
3051 OCMReject([flutterViewController2 touchesBegan:touches2 withEvent:event2]);
3053 NSSet* touches3 = [NSSet setWithObject:@1];
3054 id event3 = OCMClassMock([UIEvent
class]);
3055 [forwardGectureRecognizer touchesMoved:touches3 withEvent:event3];
3056 OCMVerify([flutterViewController touchesMoved:touches3 withEvent:event3]);
3057 OCMReject([flutterViewController2 touchesMoved:touches3 withEvent:event3]);
3059 NSSet* touches4 = [NSSet setWithObject:@1];
3060 id event4 = OCMClassMock([UIEvent
class]);
3061 [forwardGectureRecognizer touchesEnded:touches4 withEvent:event4];
3062 OCMVerify([flutterViewController touchesEnded:touches4 withEvent:event4]);
3063 OCMReject([flutterViewController2 touchesEnded:touches4 withEvent:event4]);
3065 NSSet* touches5 = [NSSet setWithObject:@1];
3066 id event5 = OCMClassMock([UIEvent
class]);
3067 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
3068 OCMVerify([flutterViewController touchesEnded:touches5 withEvent:event5]);
3069 OCMReject([flutterViewController2 touchesEnded:touches5 withEvent:event5]);
3073 NSSet* touches6 = [NSSet setWithObject:@1];
3074 id event6 = OCMClassMock([UIEvent
class]);
3075 [forwardGectureRecognizer touchesBegan:touches6 withEvent:event6];
3076 OCMVerify([flutterViewController2 touchesBegan:touches6 withEvent:event6]);
3077 OCMReject([flutterViewController touchesBegan:touches6 withEvent:event6]);
3080 NSSet* touches7 = [NSSet setWithObject:@1];
3081 id event7 = OCMClassMock([UIEvent
class]);
3082 [forwardGectureRecognizer touchesMoved:touches7 withEvent:event7];
3083 OCMVerify([flutterViewController2 touchesMoved:touches7 withEvent:event7]);
3084 OCMReject([flutterViewController touchesMoved:touches7 withEvent:event7]);
3086 NSSet* touches8 = [NSSet setWithObject:@1];
3087 id event8 = OCMClassMock([UIEvent
class]);
3088 [forwardGectureRecognizer touchesEnded:touches8 withEvent:event8];
3089 OCMVerify([flutterViewController2 touchesEnded:touches8 withEvent:event8]);
3090 OCMReject([flutterViewController touchesEnded:touches8 withEvent:event8]);
3092 [flutterPlatformViewsController
reset];
3095 - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled {
3096 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3098 flutter::TaskRunners runners(
self.name.UTF8String,
3099 GetDefaultTaskRunner(),
3100 GetDefaultTaskRunner(),
3101 GetDefaultTaskRunner(),
3102 GetDefaultTaskRunner());
3105 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3106 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3109 flutterPlatformViewsController,
3112 std::make_shared<fml::SyncSwitch>());
3116 [flutterPlatformViewsController
3118 withId:@"MockFlutterPlatformView"
3122 [flutterPlatformViewsController
3126 @"viewType" : @"MockFlutterPlatformView"
3134 while (touchInteceptorView != nil &&
3136 touchInteceptorView = touchInteceptorView.superview;
3138 XCTAssertNotNil(touchInteceptorView);
3141 UIGestureRecognizer* forwardGectureRecognizer = nil;
3142 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3144 forwardGectureRecognizer = gestureRecognizer;
3151 NSSet* touches1 = [NSSet setWithObject:@1];
3152 id event1 = OCMClassMock([UIEvent
class]);
3153 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3155 [forwardGectureRecognizer touchesCancelled:touches1 withEvent:event1];
3156 OCMVerify([flutterViewController forceTouchesCancelled:touches1]);
3158 [flutterPlatformViewsController
reset];
3161 - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer {
3162 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3164 flutter::TaskRunners runners(
self.name.UTF8String,
3165 GetDefaultTaskRunner(),
3166 GetDefaultTaskRunner(),
3167 GetDefaultTaskRunner(),
3168 GetDefaultTaskRunner());
3171 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3172 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3175 flutterPlatformViewsController,
3178 std::make_shared<fml::SyncSwitch>());
3182 [flutterPlatformViewsController
3184 withId:@"MockFlutterPlatformView"
3188 [flutterPlatformViewsController
3192 @"viewType" : @"MockFlutterPlatformView"
3200 while (touchInteceptorView != nil &&
3202 touchInteceptorView = touchInteceptorView.superview;
3204 XCTAssertNotNil(touchInteceptorView);
3207 __block UIGestureRecognizer* forwardGestureRecognizer = nil;
3208 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3210 forwardGestureRecognizer = gestureRecognizer;
3217 NSSet* touches1 = [NSSet setWithObject:@1];
3218 id event1 = OCMClassMock([UIEvent
class]);
3219 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3220 @"Forwarding gesture recognizer must start with possible state.");
3221 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3222 [forwardGestureRecognizer touchesEnded:touches1 withEvent:event1];
3223 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3224 @"Forwarding gesture recognizer must end with failed state.");
3226 XCTestExpectation* touchEndedExpectation =
3227 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3228 dispatch_async(dispatch_get_main_queue(), ^{
3230 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3231 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3232 forwardGestureRecognizer = gestureRecognizer;
3236 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3237 @"Forwarding gesture recognizer must be reset to possible state.");
3238 [touchEndedExpectation fulfill];
3240 [
self waitForExpectationsWithTimeout:30 handler:nil];
3242 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3243 @"Forwarding gesture recognizer must start with possible state.");
3244 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3245 [forwardGestureRecognizer touchesCancelled:touches1 withEvent:event1];
3246 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3247 @"Forwarding gesture recognizer must end with failed state.");
3248 XCTestExpectation* touchCancelledExpectation =
3249 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3250 dispatch_async(dispatch_get_main_queue(), ^{
3252 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3253 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3254 forwardGestureRecognizer = gestureRecognizer;
3258 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3259 @"Forwarding gesture recognizer must be reset to possible state.");
3260 [touchCancelledExpectation fulfill];
3262 [
self waitForExpectationsWithTimeout:30 handler:nil];
3264 [flutterPlatformViewsController reset];
3268 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWebView {
3269 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3271 flutter::TaskRunners runners(
self.name.UTF8String,
3272 GetDefaultTaskRunner(),
3273 GetDefaultTaskRunner(),
3274 GetDefaultTaskRunner(),
3275 GetDefaultTaskRunner());
3278 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3279 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3282 flutterPlatformViewsController,
3285 std::make_shared<fml::SyncSwitch>());
3289 [flutterPlatformViewsController
3295 [flutterPlatformViewsController
3298 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3305 while (touchInteceptorView != nil &&
3307 touchInteceptorView = touchInteceptorView.superview;
3309 XCTAssertNotNil(touchInteceptorView);
3311 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3312 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3313 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3320 BOOL shouldReAddDelayingRecognizer = NO;
3321 if (@available(iOS 26.0, *)) {
3324 }
else if (@available(iOS 18.2, *)) {
3325 shouldReAddDelayingRecognizer = YES;
3327 if (shouldReAddDelayingRecognizer) {
3329 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3330 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3332 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3333 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3338 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWrapperWebView {
3339 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3341 flutter::TaskRunners runners(
self.name.UTF8String,
3342 GetDefaultTaskRunner(),
3343 GetDefaultTaskRunner(),
3344 GetDefaultTaskRunner(),
3345 GetDefaultTaskRunner());
3348 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3349 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3352 flutterPlatformViewsController,
3355 std::make_shared<fml::SyncSwitch>());
3359 [flutterPlatformViewsController
3361 withId:@"MockWrapperWebView"
3365 [flutterPlatformViewsController
3368 arguments:@{@"id" : @2, @"viewType" : @"MockWrapperWebView"}]
3375 while (touchInteceptorView != nil &&
3377 touchInteceptorView = touchInteceptorView.superview;
3379 XCTAssertNotNil(touchInteceptorView);
3381 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3382 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3383 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3390 BOOL shouldReAddDelayingRecognizer = NO;
3391 if (@available(iOS 26.0, *)) {
3394 }
else if (@available(iOS 18.2, *)) {
3395 shouldReAddDelayingRecognizer = YES;
3397 if (shouldReAddDelayingRecognizer) {
3399 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3400 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3402 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3403 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3408 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNestedWrapperWebView {
3409 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3411 flutter::TaskRunners runners(
self.name.UTF8String,
3412 GetDefaultTaskRunner(),
3413 GetDefaultTaskRunner(),
3414 GetDefaultTaskRunner(),
3415 GetDefaultTaskRunner());
3418 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3419 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3422 flutterPlatformViewsController,
3425 std::make_shared<fml::SyncSwitch>());
3429 [flutterPlatformViewsController
3431 withId:@"MockNestedWrapperWebView"
3435 [flutterPlatformViewsController
3439 @"viewType" : @"MockNestedWrapperWebView"
3447 while (touchInteceptorView != nil &&
3449 touchInteceptorView = touchInteceptorView.superview;
3451 XCTAssertNotNil(touchInteceptorView);
3453 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3454 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3455 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3462 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3463 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3467 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNonWebView {
3468 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3470 flutter::TaskRunners runners(
self.name.UTF8String,
3471 GetDefaultTaskRunner(),
3472 GetDefaultTaskRunner(),
3473 GetDefaultTaskRunner(),
3474 GetDefaultTaskRunner());
3477 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3478 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3481 flutterPlatformViewsController,
3484 std::make_shared<fml::SyncSwitch>());
3488 [flutterPlatformViewsController
3490 withId:@"MockFlutterPlatformView"
3494 [flutterPlatformViewsController
3498 @"viewType" : @"MockFlutterPlatformView"
3506 while (touchInteceptorView != nil &&
3508 touchInteceptorView = touchInteceptorView.superview;
3510 XCTAssertNotNil(touchInteceptorView);
3512 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3513 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3514 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3521 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3522 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3526 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForSimpleWebView {
3527 if (@available(iOS 26.0, *)) {
3528 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3530 flutter::TaskRunners runners(
self.name.UTF8String,
3531 GetDefaultTaskRunner(),
3532 GetDefaultTaskRunner(),
3533 GetDefaultTaskRunner(),
3534 GetDefaultTaskRunner());
3537 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3538 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3541 flutterPlatformViewsController,
3544 std::make_shared<fml::SyncSwitch>());
3548 [flutterPlatformViewsController
3554 [flutterPlatformViewsController
3557 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3564 while (touchInteceptorView != nil &&
3566 touchInteceptorView = touchInteceptorView.superview;
3568 XCTAssertNotNil(touchInteceptorView);
3582 root.gestureRecognizers = nil;
3583 for (UIView* subview in root.subviews) {
3584 [subview removeFromSuperview];
3588 [root addGestureRecognizer:normalRecognizer0];
3590 UIView* child1 = [[UIView alloc] init];
3591 [root addSubview:child1];
3593 [child1 addGestureRecognizer:normalRecognizer1];
3595 UIView* child2 = [[UIView alloc] init];
3596 [root addSubview:child2];
3598 [child2 addGestureRecognizer:normalRecognizer2];
3600 UIView* child2_1 = [[UIView alloc] init];
3601 [child2 addSubview:child2_1];
3603 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3605 UIView* child2_2 = [[UIView alloc] init];
3606 [child2 addSubview:child2_2];
3608 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3613 [root addGestureRecognizer:targetRecognizer0];
3617 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3621 NSArray* normalRecognizers = @[
3622 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3626 NSArray* targetRecognizers = @[ targetRecognizer0, targetRecognizer2_2 ];
3628 NSArray* expectedEmptyHistory = @[];
3629 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3632 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3635 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3641 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForMultipleWebViewInDifferentBranches {
3642 if (@available(iOS 26.0, *)) {
3643 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3645 flutter::TaskRunners runners(
self.name.UTF8String,
3646 GetDefaultTaskRunner(),
3647 GetDefaultTaskRunner(),
3648 GetDefaultTaskRunner(),
3649 GetDefaultTaskRunner());
3652 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3653 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3656 flutterPlatformViewsController,
3659 std::make_shared<fml::SyncSwitch>());
3663 [flutterPlatformViewsController
3665 withId:@"MockWrapperWebView"
3669 [flutterPlatformViewsController
3673 @"viewType" : @"MockWrapperWebView"
3681 while (touchInteceptorView != nil &&
3683 touchInteceptorView = touchInteceptorView.superview;
3685 XCTAssertNotNil(touchInteceptorView);
3703 for (UIView* subview in root.subviews) {
3704 [subview removeFromSuperview];
3708 [root addGestureRecognizer:normalRecognizer0];
3710 UIView* child1 = [[UIView alloc] init];
3711 [root addSubview:child1];
3713 [child1 addGestureRecognizer:normalRecognizer1];
3715 UIView* child2 = [[WKWebView alloc] init];
3716 child2.gestureRecognizers = nil;
3717 for (UIView* subview in child2.subviews) {
3718 [subview removeFromSuperview];
3720 [root addSubview:child2];
3722 [child2 addGestureRecognizer:normalRecognizer2];
3724 UIView* child2_1 = [[UIView alloc] init];
3725 [child2 addSubview:child2_1];
3727 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3729 UIView* child2_2 = [[UIView alloc] init];
3730 [child2 addSubview:child2_2];
3732 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3734 UIView* child3 = [[UIView alloc] init];
3735 [root addSubview:child3];
3737 [child3 addGestureRecognizer:normalRecognizer3];
3739 UIView* child3_1 = [[WKWebView alloc] init];
3740 child3_1.gestureRecognizers = nil;
3741 for (UIView* subview in child3_1.subviews) {
3742 [subview removeFromSuperview];
3744 [child3 addSubview:child3_1];
3746 [child3_1 addGestureRecognizer:normalRecognizer3_1];
3748 UIView* child3_1_1 = [[UIView alloc] init];
3749 [child3_1 addSubview:child3_1_1];
3751 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
3753 UIView* child3_1_2 = [[UIView alloc] init];
3754 [child3_1 addSubview:child3_1_2];
3756 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
3762 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3766 [child3_1_2 addGestureRecognizer:targetRecognizer3_1_2];
3770 NSArray* normalRecognizers = @[
3771 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3772 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
3773 normalRecognizer3_1_2
3775 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2 ];
3777 NSArray* expectedEmptyHistory = @[];
3778 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3781 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3785 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3791 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForNestedMultipleWebView {
3792 if (@available(iOS 26.0, *)) {
3793 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3795 flutter::TaskRunners runners(
self.name.UTF8String,
3796 GetDefaultTaskRunner(),
3797 GetDefaultTaskRunner(),
3798 GetDefaultTaskRunner(),
3799 GetDefaultTaskRunner());
3802 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3803 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3806 flutterPlatformViewsController,
3809 std::make_shared<fml::SyncSwitch>());
3813 [flutterPlatformViewsController
3819 [flutterPlatformViewsController
3822 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3829 while (touchInteceptorView != nil &&
3831 touchInteceptorView = touchInteceptorView.superview;
3833 XCTAssertNotNil(touchInteceptorView);
3853 root.gestureRecognizers = nil;
3854 for (UIView* subview in root.subviews) {
3855 [subview removeFromSuperview];
3859 [root addGestureRecognizer:normalRecognizer0];
3861 UIView* child1 = [[UIView alloc] init];
3862 [root addSubview:child1];
3864 [child1 addGestureRecognizer:normalRecognizer1];
3866 UIView* child2 = [[UIView alloc] init];
3867 [root addSubview:child2];
3869 [child2 addGestureRecognizer:normalRecognizer2];
3871 UIView* child2_1 = [[UIView alloc] init];
3872 [child2 addSubview:child2_1];
3874 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3876 UIView* child2_2 = [[UIView alloc] init];
3877 [child2 addSubview:child2_2];
3879 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3881 UIView* child3 = [[UIView alloc] init];
3882 [root addSubview:child3];
3884 [child3 addGestureRecognizer:normalRecognizer3];
3886 UIView* child3_1 = [[WKWebView alloc] init];
3887 child3_1.gestureRecognizers = nil;
3888 for (UIView* subview in child3_1.subviews) {
3889 [subview removeFromSuperview];
3891 [child3 addSubview:child3_1];
3893 [child3_1 addGestureRecognizer:normalRecognizer3_1];
3895 UIView* child3_1_1 = [[UIView alloc] init];
3896 [child3_1 addSubview:child3_1_1];
3898 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
3900 UIView* child3_1_2 = [[UIView alloc] init];
3901 [child3_1 addSubview:child3_1_2];
3903 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
3905 UIView* child3_1_2_1 = [[UIView alloc] init];
3906 [child3_1_2 addSubview:child3_1_2_1];
3908 [child3_1_2_1 addGestureRecognizer:normalRecognizer3_1_2_1];
3910 UIView* child3_1_2_2 = [[UIView alloc] init];
3911 [child3_1_2 addSubview:child3_1_2_2];
3913 [child3_1_2_2 addGestureRecognizer:normalRecognizer3_1_2_2];
3919 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3923 [child3_1_2_2 addGestureRecognizer:targetRecognizer3_1_2_2];
3927 NSArray* normalRecognizers = @[
3928 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3929 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
3930 normalRecognizer3_1_2, normalRecognizer3_1_2_1, normalRecognizer3_1_2_2
3933 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2_2 ];
3935 NSArray* expectedEmptyHistory = @[];
3936 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3939 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3943 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3948 - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
3949 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3951 flutter::TaskRunners runners(
self.name.UTF8String,
3952 GetDefaultTaskRunner(),
3953 GetDefaultTaskRunner(),
3954 GetDefaultTaskRunner(),
3955 GetDefaultTaskRunner());
3958 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3959 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3962 flutterPlatformViewsController,
3965 std::make_shared<fml::SyncSwitch>());
3969 [flutterPlatformViewsController
3971 withId:@"MockFlutterPlatformView"
3975 [flutterPlatformViewsController
3979 @"viewType" : @"MockFlutterPlatformView"
3986 flutter::MutatorsStack stack;
3987 flutter::DlMatrix finalMatrix;
3989 auto embeddedViewParams_1 =
3990 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
3992 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3993 withParams:std::move(embeddedViewParams_1)];
3994 [flutterPlatformViewsController
3998 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
3999 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4000 nullptr, framebuffer_info,
4001 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return false; },
4002 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4003 flutter::DlISize(800, 600));
4004 XCTAssertFalse([flutterPlatformViewsController
4005 submitFrame:std::move(mock_surface)
4006 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4008 auto embeddedViewParams_2 =
4009 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4010 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4011 withParams:std::move(embeddedViewParams_2)];
4012 [flutterPlatformViewsController
4016 auto mock_surface_submit_true = std::make_unique<flutter::SurfaceFrame>(
4017 nullptr, framebuffer_info,
4018 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4019 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4020 flutter::DlISize(800, 600));
4021 XCTAssertTrue([flutterPlatformViewsController
4022 submitFrame:std::move(mock_surface_submit_true)
4023 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4027 testFlutterPlatformViewControllerResetDeallocsPlatformViewWhenRootViewsNotBindedToFlutterView {
4028 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4030 flutter::TaskRunners runners(
self.name.UTF8String,
4031 GetDefaultTaskRunner(),
4032 GetDefaultTaskRunner(),
4033 GetDefaultTaskRunner(),
4034 GetDefaultTaskRunner());
4037 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4038 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4041 flutterPlatformViewsController,
4044 std::make_shared<fml::SyncSwitch>());
4046 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4047 flutterPlatformViewsController.
flutterView = flutterView;
4051 [flutterPlatformViewsController
4053 withId:@"MockFlutterPlatformView"
4059 [flutterPlatformViewsController
4063 @"viewType" : @"MockFlutterPlatformView"
4067 flutter::MutatorsStack stack;
4068 flutter::DlMatrix finalMatrix;
4069 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
4070 finalMatrix, flutter::DlSize(300, 300), stack);
4071 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4072 withParams:std::move(embeddedViewParams)];
4078 [flutterPlatformViewsController
reset];
4083 - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
4084 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4086 flutter::TaskRunners runners(
self.name.UTF8String,
4087 GetDefaultTaskRunner(),
4088 GetDefaultTaskRunner(),
4089 GetDefaultTaskRunner(),
4090 GetDefaultTaskRunner());
4093 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4094 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4097 flutterPlatformViewsController,
4100 std::make_shared<fml::SyncSwitch>());
4102 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4103 flutterPlatformViewsController.
flutterView = flutterView;
4107 [flutterPlatformViewsController
4109 withId:@"MockFlutterPlatformView"
4114 [flutterPlatformViewsController
4118 @"viewType" : @"MockFlutterPlatformView"
4123 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4124 flutter::MutatorsStack stack;
4125 flutter::DlMatrix finalMatrix;
4126 auto embeddedViewParams1 =
4127 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4128 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4129 withParams:std::move(embeddedViewParams1)];
4130 [flutterPlatformViewsController
4137 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4140 auto embeddedViewParams2 =
4141 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4142 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4143 withParams:std::move(embeddedViewParams2)];
4144 [flutterPlatformViewsController
4152 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithDifferentViewHierarchy {
4153 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4155 flutter::TaskRunners runners(
self.name.UTF8String,
4156 GetDefaultTaskRunner(),
4157 GetDefaultTaskRunner(),
4158 GetDefaultTaskRunner(),
4159 GetDefaultTaskRunner());
4162 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4163 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4166 flutterPlatformViewsController,
4169 std::make_shared<fml::SyncSwitch>());
4171 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4172 flutterPlatformViewsController.
flutterView = flutterView;
4176 [flutterPlatformViewsController
4178 withId:@"MockFlutterPlatformView"
4182 [flutterPlatformViewsController
4186 @"viewType" : @"MockFlutterPlatformView"
4192 [flutterPlatformViewsController
4196 @"viewType" : @"MockFlutterPlatformView"
4201 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4202 flutter::MutatorsStack stack;
4203 flutter::DlMatrix finalMatrix;
4204 auto embeddedViewParams1 =
4205 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4206 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4207 withParams:std::move(embeddedViewParams1)];
4209 auto embeddedViewParams2 =
4210 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4211 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4212 withParams:std::move(embeddedViewParams2)];
4214 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4215 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4216 nullptr, framebuffer_info,
4217 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4218 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4219 flutter::DlISize(800, 600),
nullptr,
true);
4220 XCTAssertTrue([flutterPlatformViewsController
4221 submitFrame:std::move(mock_surface)
4222 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4225 UIView* clippingView1 = view1.superview.superview;
4226 UIView* clippingView2 = view2.superview.superview;
4227 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4228 [flutterView.subviews indexOfObject:clippingView2],
4229 @"The first clipping view should be added before the second clipping view.");
4232 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4234 embeddedViewParams2 =
4235 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4236 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4237 withParams:std::move(embeddedViewParams2)];
4239 embeddedViewParams1 =
4240 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4241 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4242 withParams:std::move(embeddedViewParams1)];
4244 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4245 nullptr, framebuffer_info,
4246 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4247 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4248 flutter::DlISize(800, 600),
nullptr,
true);
4249 XCTAssertTrue([flutterPlatformViewsController
4250 submitFrame:std::move(mock_surface)
4251 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4253 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] >
4254 [flutterView.subviews indexOfObject:clippingView2],
4255 @"The first clipping view should be added after the second clipping view.");
4259 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithSameViewHierarchy {
4260 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4262 flutter::TaskRunners runners(
self.name.UTF8String,
4263 GetDefaultTaskRunner(),
4264 GetDefaultTaskRunner(),
4265 GetDefaultTaskRunner(),
4266 GetDefaultTaskRunner());
4269 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4270 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4273 flutterPlatformViewsController,
4276 std::make_shared<fml::SyncSwitch>());
4278 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4279 flutterPlatformViewsController.
flutterView = flutterView;
4283 [flutterPlatformViewsController
4285 withId:@"MockFlutterPlatformView"
4289 [flutterPlatformViewsController
4293 @"viewType" : @"MockFlutterPlatformView"
4299 [flutterPlatformViewsController
4303 @"viewType" : @"MockFlutterPlatformView"
4308 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4309 flutter::MutatorsStack stack;
4310 flutter::DlMatrix finalMatrix;
4311 auto embeddedViewParams1 =
4312 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4313 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4314 withParams:std::move(embeddedViewParams1)];
4316 auto embeddedViewParams2 =
4317 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4318 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4319 withParams:std::move(embeddedViewParams2)];
4321 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4322 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4323 nullptr, framebuffer_info,
4324 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4325 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4326 flutter::DlISize(800, 600),
nullptr,
true);
4327 XCTAssertTrue([flutterPlatformViewsController
4328 submitFrame:std::move(mock_surface)
4329 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4332 UIView* clippingView1 = view1.superview.superview;
4333 UIView* clippingView2 = view2.superview.superview;
4334 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4335 [flutterView.subviews indexOfObject:clippingView2],
4336 @"The first clipping view should be added before the second clipping view.");
4339 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4341 embeddedViewParams1 =
4342 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4343 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4344 withParams:std::move(embeddedViewParams1)];
4346 embeddedViewParams2 =
4347 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4348 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4349 withParams:std::move(embeddedViewParams2)];
4351 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4352 nullptr, framebuffer_info,
4353 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4354 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4355 flutter::DlISize(800, 600),
nullptr,
true);
4356 XCTAssertTrue([flutterPlatformViewsController
4357 submitFrame:std::move(mock_surface)
4358 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4360 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4361 [flutterView.subviews indexOfObject:clippingView2],
4362 @"The first clipping view should be added before the second clipping view.");
4365 - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
4366 unsigned char pixel[4] = {0};
4368 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
4371 CGContextRef context =
4372 CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace,
4373 static_cast<uint32_t
>(kCGBitmapAlphaInfoMask) &
4374 static_cast<uint32_t
>(kCGImageAlphaPremultipliedLast));
4375 CGContextTranslateCTM(context, -point.x, -point.y);
4376 [view.layer renderInContext:context];
4378 CGContextRelease(context);
4379 CGColorSpaceRelease(colorSpace);
4384 - (void)testHasFirstResponderInViewHierarchySubtree_viewItselfBecomesFirstResponder {
4386 UIWindow* window = [[UIWindow alloc] init];
4387 UITextField* textField = [[UITextField alloc] init];
4388 [window addSubview:textField];
4390 [textField becomeFirstResponder];
4391 XCTAssertTrue(textField.isFirstResponder);
4392 XCTAssertTrue(textField.flt_hasFirstResponderInViewHierarchySubtree);
4393 [textField resignFirstResponder];
4394 XCTAssertFalse(textField.isFirstResponder);
4395 XCTAssertFalse(textField.flt_hasFirstResponderInViewHierarchySubtree);
4398 - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstResponder {
4400 UIWindow* window = [[UIWindow alloc] init];
4401 UIView* view = [[UIView alloc] init];
4402 UIView* childView = [[UIView alloc] init];
4403 UITextField* textField = [[UITextField alloc] init];
4404 [window addSubview:view];
4405 [view addSubview:childView];
4406 [childView addSubview:textField];
4408 [textField becomeFirstResponder];
4409 XCTAssertTrue(textField.isFirstResponder);
4410 XCTAssertTrue(view.flt_hasFirstResponderInViewHierarchySubtree);
4411 [textField resignFirstResponder];
4412 XCTAssertFalse(textField.isFirstResponder);
4413 XCTAssertFalse(view.flt_hasFirstResponderInViewHierarchySubtree);
4416 - (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle {
4422 CGRect newRect = CGRectMake(0, 0, 10, 10);
4426 NSSet* set1 = [NSSet setWithObjects:view1, view2, nil];
4427 NSSet* set2 = [NSSet setWithObjects:view3, view4, nil];
4428 XCTAssertEqualObjects(set1, set2);
4429 XCTAssertTrue(CGRectEqualToRect(view3.frame, newRect));
4430 XCTAssertTrue(CGRectEqualToRect(view4.frame, newRect));
4433 - (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity {
4438 XCTAssertNotEqual(view1, view3);
4439 XCTAssertNotEqual(view2, view3);
4442 - (void)testMaskViewsReleasedWhenPoolIsReleased {
4443 __weak UIView* weakView;
4448 XCTAssertNotNil(weakView);
4450 XCTAssertNil(weakView);
4453 - (void)testClipMaskViewIsReused {
4454 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4456 flutter::TaskRunners runners(
self.name.UTF8String,
4457 GetDefaultTaskRunner(),
4458 GetDefaultTaskRunner(),
4459 GetDefaultTaskRunner(),
4460 GetDefaultTaskRunner());
4463 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4464 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4467 flutterPlatformViewsController,
4470 std::make_shared<fml::SyncSwitch>());
4474 [flutterPlatformViewsController
4476 withId:@"MockFlutterPlatformView"
4480 [flutterPlatformViewsController
4484 @"viewType" : @"MockFlutterPlatformView"
4489 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4490 flutterPlatformViewsController.
flutterView = flutterView;
4492 flutter::MutatorsStack stack1;
4494 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4495 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4496 stack1.PushTransform(screenScaleMatrix);
4498 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4499 stack1.PushClipRect(rect);
4501 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4502 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4504 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4505 withParams:std::move(embeddedViewParams1)];
4506 [flutterPlatformViewsController
4511 UIView* maskView1 = childClippingView1.maskView;
4512 XCTAssertNotNil(maskView1);
4515 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(100, 100)];
4516 flutter::MutatorsStack stack2;
4517 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4518 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4519 auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
4520 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4521 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4522 withParams:std::move(embeddedViewParams3)];
4523 [flutterPlatformViewsController
4530 [flutterPlatformViewsController
4534 @"viewType" : @"MockFlutterPlatformView"
4538 auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
4539 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4540 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4541 withParams:std::move(embeddedViewParams4)];
4542 [flutterPlatformViewsController
4548 UIView* maskView2 = childClippingView2.maskView;
4549 XCTAssertEqual(maskView1, maskView2);
4550 XCTAssertNotNil(childClippingView2.maskView);
4551 XCTAssertNil(childClippingView1.maskView);
4554 - (void)testDifferentClipMaskViewIsUsedForEachView {
4555 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4557 flutter::TaskRunners runners(
self.name.UTF8String,
4558 GetDefaultTaskRunner(),
4559 GetDefaultTaskRunner(),
4560 GetDefaultTaskRunner(),
4561 GetDefaultTaskRunner());
4564 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4565 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4568 flutterPlatformViewsController,
4571 std::make_shared<fml::SyncSwitch>());
4575 [flutterPlatformViewsController
4577 withId:@"MockFlutterPlatformView"
4582 [flutterPlatformViewsController
4586 @"viewType" : @"MockFlutterPlatformView"
4592 [flutterPlatformViewsController
4596 @"viewType" : @"MockFlutterPlatformView"
4602 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4603 flutterPlatformViewsController.
flutterView = flutterView;
4605 flutter::MutatorsStack stack1;
4607 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4608 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4609 stack1.PushTransform(screenScaleMatrix);
4611 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4612 stack1.PushClipRect(rect);
4614 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4615 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4617 flutter::MutatorsStack stack2;
4618 stack2.PushClipRect(rect);
4619 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4620 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4622 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4623 withParams:std::move(embeddedViewParams1)];
4624 [flutterPlatformViewsController
4628 UIView* childClippingView1 = view1.superview.superview;
4630 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4631 withParams:std::move(embeddedViewParams2)];
4632 [flutterPlatformViewsController
4636 UIView* childClippingView2 = view2.superview.superview;
4637 UIView* maskView1 = childClippingView1.maskView;
4638 UIView* maskView2 = childClippingView2.maskView;
4639 XCTAssertNotEqual(maskView1, maskView2);
4642 - (void)testMaskViewUsesCAShapeLayerAsTheBackingLayer {
4643 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4645 flutter::TaskRunners runners(
self.name.UTF8String,
4646 GetDefaultTaskRunner(),
4647 GetDefaultTaskRunner(),
4648 GetDefaultTaskRunner(),
4649 GetDefaultTaskRunner());
4652 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4653 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4656 flutterPlatformViewsController,
4659 std::make_shared<fml::SyncSwitch>());
4663 [flutterPlatformViewsController
4665 withId:@"MockFlutterPlatformView"
4670 [flutterPlatformViewsController
4674 @"viewType" : @"MockFlutterPlatformView"
4679 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4680 flutterPlatformViewsController.
flutterView = flutterView;
4682 flutter::MutatorsStack stack1;
4684 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4685 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4686 stack1.PushTransform(screenScaleMatrix);
4688 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4689 stack1.PushClipRect(rect);
4691 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4692 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4694 flutter::MutatorsStack stack2;
4695 stack2.PushClipRect(rect);
4696 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4697 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4699 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4700 withParams:std::move(embeddedViewParams1)];
4701 [flutterPlatformViewsController
4707 UIView* maskView = childClippingView.maskView;
4708 XCTAssert([maskView.layer isKindOfClass:[CAShapeLayer
class]],
4709 @"Mask view must use CAShapeLayer as its backing layer.");
4717 - (BOOL)validateOneVisualEffectView:(UIView*)visualEffectView
4718 expectedFrame:(CGRect)frame
4719 inputRadius:(CGFloat)inputRadius {
4720 XCTAssertTrue(CGRectEqualToRect(visualEffectView.frame, frame));
4721 for (UIView* view in visualEffectView.subviews) {
4722 if (![NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
4725 XCTAssertEqual(view.layer.filters.count, 1u);
4726 NSObject* filter = view.layer.filters.firstObject;
4728 XCTAssertEqualObjects([filter valueForKey:
@"name"],
@"gaussianBlur");
4730 NSObject* inputRadiusInFilter = [filter valueForKey:@"inputRadius"];
4731 XCTAssertTrue([inputRadiusInFilter isKindOfClass:[NSNumber
class]] &&
4732 flutter::BlurRadiusEqualToBlurRadius(((NSNumber*)inputRadiusInFilter).floatValue,
4739 - (void)testDisposingViewInCompositionOrderDoNotCrash {
4740 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4742 flutter::TaskRunners runners(
self.name.UTF8String,
4743 GetDefaultTaskRunner(),
4744 GetDefaultTaskRunner(),
4745 GetDefaultTaskRunner(),
4746 GetDefaultTaskRunner());
4749 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4750 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4753 flutterPlatformViewsController,
4756 std::make_shared<fml::SyncSwitch>());
4758 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4759 flutterPlatformViewsController.
flutterView = flutterView;
4763 [flutterPlatformViewsController
4765 withId:@"MockFlutterPlatformView"
4770 [flutterPlatformViewsController
4774 @"viewType" : @"MockFlutterPlatformView"
4777 [flutterPlatformViewsController
4781 @"viewType" : @"MockFlutterPlatformView"
4788 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4789 flutter::MutatorsStack stack;
4790 flutter::DlMatrix finalMatrix;
4791 auto embeddedViewParams0 = std::make_unique<flutter::EmbeddedViewParams>(
4792 finalMatrix, flutter::DlSize(300, 300), stack);
4793 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4794 withParams:std::move(embeddedViewParams0)];
4796 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4797 finalMatrix, flutter::DlSize(300, 300), stack);
4798 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4799 withParams:std::move(embeddedViewParams1)];
4803 XCTestExpectation* expectation = [
self expectationWithDescription:@"dispose call ended."];
4805 [expectation fulfill];
4808 [flutterPlatformViewsController
4811 [
self waitForExpectationsWithTimeout:30 handler:nil];
4813 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4814 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4815 nullptr, framebuffer_info,
4816 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4817 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4818 flutter::DlISize(800, 600),
nullptr,
4820 XCTAssertTrue([flutterPlatformViewsController
4821 submitFrame:std::move(mock_surface)
4822 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4826 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:0]);
4827 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4833 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4834 flutter::MutatorsStack stack;
4835 flutter::DlMatrix finalMatrix;
4836 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4837 finalMatrix, flutter::DlSize(300, 300), stack);
4838 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4839 withParams:std::move(embeddedViewParams1)];
4841 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4842 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4843 nullptr, framebuffer_info,
4844 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4845 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4846 flutter::DlISize(800, 600),
nullptr,
true);
4847 XCTAssertTrue([flutterPlatformViewsController
4848 submitFrame:std::move(mock_surface)
4849 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4853 XCTAssertNil([flutterPlatformViewsController platformViewForId:0]);
4854 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4857 - (void)testOnlyPlatformViewsAreRemovedWhenReset {
4858 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4860 flutter::TaskRunners runners(
self.name.UTF8String,
4861 GetDefaultTaskRunner(),
4862 GetDefaultTaskRunner(),
4863 GetDefaultTaskRunner(),
4864 GetDefaultTaskRunner());
4867 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4868 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4871 flutterPlatformViewsController,
4874 std::make_shared<fml::SyncSwitch>());
4878 [flutterPlatformViewsController
4880 withId:@"MockFlutterPlatformView"
4884 [flutterPlatformViewsController
4888 @"viewType" : @"MockFlutterPlatformView"
4891 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4892 flutterPlatformViewsController.
flutterView = flutterView;
4894 flutter::MutatorsStack stack;
4896 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4897 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4898 stack.PushTransform(screenScaleMatrix);
4900 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4901 stack.PushTransform(translateMatrix);
4902 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4904 auto embeddedViewParams =
4905 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4907 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4908 withParams:std::move(embeddedViewParams)];
4910 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4911 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4912 nullptr, framebuffer_info,
4913 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4914 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4915 flutter::DlISize(800, 600),
nullptr,
true);
4916 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4917 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4919 UIView* someView = [[UIView alloc] init];
4920 [flutterView addSubview:someView];
4922 [flutterPlatformViewsController
reset];
4923 XCTAssertEqual(flutterView.subviews.count, 1u);
4924 XCTAssertEqual(flutterView.subviews.firstObject, someView);
4927 - (void)testResetClearsPreviousCompositionOrder {
4928 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4930 flutter::TaskRunners runners(
self.name.UTF8String,
4931 GetDefaultTaskRunner(),
4932 GetDefaultTaskRunner(),
4933 GetDefaultTaskRunner(),
4934 GetDefaultTaskRunner());
4937 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4938 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4941 flutterPlatformViewsController,
4944 std::make_shared<fml::SyncSwitch>());
4948 [flutterPlatformViewsController
4950 withId:@"MockFlutterPlatformView"
4954 [flutterPlatformViewsController
4958 @"viewType" : @"MockFlutterPlatformView"
4961 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4962 flutterPlatformViewsController.
flutterView = flutterView;
4964 flutter::MutatorsStack stack;
4966 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4967 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4968 stack.PushTransform(screenScaleMatrix);
4970 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4971 stack.PushTransform(translateMatrix);
4972 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4974 auto embeddedViewParams =
4975 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4977 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4978 withParams:std::move(embeddedViewParams)];
4980 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4981 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4982 nullptr, framebuffer_info,
4983 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4984 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4985 flutter::DlISize(800, 600),
nullptr,
true);
4986 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4987 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4993 [flutterPlatformViewsController
reset];
4999 - (void)testNilPlatformViewDoesntCrash {
5000 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5002 flutter::TaskRunners runners(
self.name.UTF8String,
5003 GetDefaultTaskRunner(),
5004 GetDefaultTaskRunner(),
5005 GetDefaultTaskRunner(),
5006 GetDefaultTaskRunner());
5009 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5010 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5013 flutterPlatformViewsController,
5016 std::make_shared<fml::SyncSwitch>());
5020 [flutterPlatformViewsController
5022 withId:@"MockFlutterPlatformView"
5026 [flutterPlatformViewsController
5030 @"viewType" : @"MockFlutterPlatformView"
5033 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5034 flutterPlatformViewsController.
flutterView = flutterView;
5037 flutter::MutatorsStack stack;
5039 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5040 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5041 stack.PushTransform(screenScaleMatrix);
5043 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
5044 stack.PushTransform(translateMatrix);
5045 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
5047 auto embeddedViewParams =
5048 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5050 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5051 withParams:std::move(embeddedViewParams)];
5053 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5054 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5055 nullptr, framebuffer_info,
5056 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5057 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
5058 flutter::DlISize(800, 600),
nullptr,
true);
5059 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5060 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5062 XCTAssertEqual(flutterView.subviews.count, 1u);
5065 - (void)testFlutterTouchInterceptingViewLinksToAccessibilityContainer {
5067 NSObject* container = [[NSObject alloc] init];
5068 [touchInteceptorView setFlutterAccessibilityContainer:container];
5069 XCTAssertEqualObjects([touchInteceptorView accessibilityContainer], container);
5072 - (void)testLayerPool {
5076 XCTAssertTrue(
engine.platformView !=
nullptr);
5077 auto ios_context =
engine.platformView->GetIosContext();
5082 pool.
CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
5083 XCTAssertEqual(pool.size(), 1u);
5084 pool.CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
5085 XCTAssertEqual(pool.size(), 2u);
5088 pool.RecycleLayers();
5089 XCTAssertEqual(pool.size(), 2u);
5092 auto unused_layers = pool.RemoveUnusedLayers();
5093 XCTAssertEqual(unused_layers.size(), 2u);
5094 XCTAssertEqual(pool.size(), 1u);
5097 - (void)testFlutterPlatformViewControllerSubmitFramePreservingFrameDamage {
5098 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5100 flutter::TaskRunners runners(
self.name.UTF8String,
5101 GetDefaultTaskRunner(),
5102 GetDefaultTaskRunner(),
5103 GetDefaultTaskRunner(),
5104 GetDefaultTaskRunner());
5107 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5108 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5111 flutterPlatformViewsController,
5114 std::make_shared<fml::SyncSwitch>());
5116 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5117 flutterPlatformViewsController.
flutterView = flutterView;
5121 [flutterPlatformViewsController
5123 withId:@"MockFlutterPlatformView"
5127 [flutterPlatformViewsController
5131 @"viewType" : @"MockFlutterPlatformView"
5136 [flutterPlatformViewsController
5140 @"viewType" : @"MockFlutterPlatformView"
5144 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
5145 flutter::MutatorsStack stack;
5146 flutter::DlMatrix finalMatrix;
5147 auto embeddedViewParams1 =
5148 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5149 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
5150 withParams:std::move(embeddedViewParams1)];
5152 auto embeddedViewParams2 =
5153 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
5154 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
5155 withParams:std::move(embeddedViewParams2)];
5157 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5158 std::optional<flutter::SurfaceFrame::SubmitInfo> submit_info;
5159 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5160 nullptr, framebuffer_info,
5161 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5162 [&](
const flutter::SurfaceFrame& surface_frame) {
5163 submit_info = surface_frame.submit_info();
5166 flutter::DlISize(800, 600),
nullptr,
5168 mock_surface->set_submit_info({
5169 .frame_damage = flutter::DlIRect::MakeWH(800, 600),
5170 .buffer_damage = flutter::DlIRect::MakeWH(400, 600),
5173 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5174 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5176 XCTAssertTrue(submit_info.has_value());
5177 XCTAssertEqual(*submit_info->frame_damage, flutter::DlIRect::MakeWH(800, 600));
5178 XCTAssertEqual(*submit_info->buffer_damage, flutter::DlIRect::MakeWH(400, 600));
5181 - (void)testClipSuperellipse {
5182 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5184 flutter::TaskRunners runners(
self.name.UTF8String,
5185 GetDefaultTaskRunner(),
5186 GetDefaultTaskRunner(),
5187 GetDefaultTaskRunner(),
5188 GetDefaultTaskRunner());
5191 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5192 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5195 flutterPlatformViewsController,
5198 std::make_shared<fml::SyncSwitch>());
5202 [flutterPlatformViewsController
5204 withId:@"MockFlutterPlatformView"
5208 [flutterPlatformViewsController
5212 @"viewType" : @"MockFlutterPlatformView"
5218 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
5219 flutterPlatformViewsController.
flutterView = flutterView;
5221 flutter::MutatorsStack stack;
5223 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5224 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5225 stack.PushTransform(screenScaleMatrix);
5227 flutter::DlRect rect = flutter::DlRect::MakeXYWH(3, 3, 5, 5);
5228 stack.PushClipRSE(flutter::DlRoundSuperellipse::MakeOval(rect));
5230 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
5231 screenScaleMatrix, flutter::DlSize(10, 10), stack);
5233 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5234 withParams:std::move(embeddedViewParams)];
5235 [flutterPlatformViewsController
5242 [flutterView addSubview:childClippingView];
5244 [flutterView setNeedsLayout];
5245 [flutterView layoutIfNeeded];
5247 CGPoint corners[] = {CGPointMake(rect.GetLeft(), rect.GetTop()),
5248 CGPointMake(rect.GetRight(), rect.GetTop()),
5249 CGPointMake(rect.GetLeft(), rect.GetBottom()),
5250 CGPointMake(rect.GetRight(), rect.GetBottom())};
5251 for (
auto point : corners) {
5252 int alpha = [
self alphaOfPoint:point onView:flutterView];
5253 XCTAssertNotEqual(alpha, 255);
5256 CGPointMake(rect.GetLeft() + rect.GetWidth() / 2, rect.GetTop() + rect.GetHeight() / 2);
5257 int alpha = [
self alphaOfPoint:center onView:flutterView];
5258 XCTAssertEqual(alpha, 255);
void(^ FlutterResult)(id _Nullable result)
NSMutableArray * backdropFilterSubviews()
void applyBlurBackdropFilters:(NSArray< PlatformViewFilter * > *filters)
FlutterClippingMaskView * getMaskViewWithFrame:(CGRect frame)
void insertViewToPoolIfNeeded:(FlutterClippingMaskView *maskView)
Storage for Overlay layers across frames.
void CreateLayer(const std::shared_ptr< IOSContext > &ios_context, MTLPixelFormat pixel_format)
Create a new overlay layer.
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)