7 #import <OCMock/OCMock.h>
8 #import <UIKit/UIKit.h>
9 #import <WebKit/WebKit.h>
10 #import <XCTest/XCTest.h>
14 #include "flutter/display_list/effects/dl_image_filters.h"
15 #include "flutter/fml/synchronization/count_down_latch.h"
16 #include "flutter/fml/thread.h"
36 - (instancetype)init {
56 @property(nonatomic, strong) NSMutableArray<NSNumber*>* toggleHistory;
60 - (instancetype)init {
63 _toggleHistory = [NSMutableArray array];
67 - (void)setEnabled:(BOOL)enabled {
68 [
super setEnabled:enabled];
69 [
self.toggleHistory addObject:@(enabled)];
81 @property(nonatomic, strong) UIView* view;
82 @property(nonatomic, assign) BOOL viewCreated;
87 - (instancetype)init {
88 if (
self = [super init]) {
96 [
self checkViewCreatedOnce];
100 - (void)checkViewCreatedOnce {
104 self.viewCreated = YES;
113 : NSObject <FlutterPlatformViewFactory>
118 viewIdentifier:(int64_t)viewId
119 arguments:(
id _Nullable)args {
126 @property(nonatomic, strong) UIView* view;
127 @property(nonatomic, assign) BOOL viewCreated;
131 - (instancetype)init {
132 if (
self = [super init]) {
133 _view = [[WKWebView alloc] init];
141 [
self checkViewCreatedOnce];
145 - (void)checkViewCreatedOnce {
149 self.viewCreated = YES;
161 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
162 viewIdentifier:(int64_t)viewId
163 arguments:(
id _Nullable)args {
172 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
173 viewIdentifier:(int64_t)viewId
174 arguments:(
id _Nullable)args {
181 @property(nonatomic, strong) UIView* view;
182 @property(nonatomic, assign) BOOL viewCreated;
186 - (instancetype)init {
187 if (
self = [super init]) {
188 _view = [[UIView alloc] init];
189 [_view addSubview:[[WKWebView alloc] init]];
197 [
self checkViewCreatedOnce];
201 - (void)checkViewCreatedOnce {
205 self.viewCreated = YES;
217 - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
218 viewIdentifier:(int64_t)viewId
219 arguments:(
id _Nullable)args {
225 @property(nonatomic, strong) UIView* view;
226 @property(nonatomic, assign) BOOL viewCreated;
230 - (instancetype)init {
231 if (
self = [super init]) {
232 _view = [[UIView alloc] init];
233 UIView* childView = [[UIView alloc] init];
234 [_view addSubview:childView];
235 [childView addSubview:[[WKWebView alloc] init]];
243 [
self checkViewCreatedOnce];
247 - (void)checkViewCreatedOnce {
251 self.viewCreated = YES;
256 : NSObject <FlutterPlatformViewFactory>
261 viewIdentifier:(int64_t)viewId
262 arguments:(
id _Nullable)args {
269 class FlutterPlatformViewsTestMockPlatformViewDelegate :
public PlatformView::Delegate {
271 void OnPlatformViewCreated(std::unique_ptr<Surface> surface)
override {}
272 void OnPlatformViewDestroyed()
override {}
273 void OnPlatformViewScheduleFrame()
override {}
274 void OnPlatformViewAddView(int64_t view_id,
275 const ViewportMetrics& viewport_metrics,
276 AddViewCallback callback)
override {}
277 void OnPlatformViewRemoveView(int64_t view_id, RemoveViewCallback callback)
override {}
278 void OnPlatformViewSendViewFocusEvent(
const ViewFocusEvent& event)
override {};
279 void OnPlatformViewSetNextFrameCallback(
const fml::closure& closure)
override {}
280 void OnPlatformViewSetViewportMetrics(int64_t view_id,
const ViewportMetrics& metrics)
override {}
281 const flutter::Settings& OnPlatformViewGetSettings()
const override {
return settings_; }
282 void OnPlatformViewDispatchPlatformMessage(std::unique_ptr<PlatformMessage> message)
override {}
283 void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet)
override {
285 void OnPlatformViewDispatchSemanticsAction(int64_t view_id,
287 SemanticsAction action,
288 fml::MallocMapping args)
override {}
289 void OnPlatformViewSetSemanticsEnabled(
bool enabled)
override {}
290 void OnPlatformViewSetAccessibilityFeatures(int32_t flags)
override {}
291 void OnPlatformViewRegisterTexture(std::shared_ptr<Texture> texture)
override {}
292 void OnPlatformViewUnregisterTexture(int64_t
texture_id)
override {}
293 void OnPlatformViewMarkTextureFrameAvailable(int64_t
texture_id)
override {}
295 void LoadDartDeferredLibrary(intptr_t loading_unit_id,
296 std::unique_ptr<const fml::Mapping> snapshot_data,
297 std::unique_ptr<const fml::Mapping> snapshot_instructions)
override {
299 void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
300 const std::string error_message,
301 bool transient)
override {}
302 void UpdateAssetResolverByType(std::unique_ptr<flutter::AssetResolver> updated_asset_resolver,
303 flutter::AssetResolver::AssetResolverType type)
override {}
308 BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2) {
309 const CGFloat epsilon = 0.01;
310 return std::abs(radius1 - radius2) < epsilon;
322 fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
323 fml::MessageLoop::EnsureInitializedForCurrentThread();
324 return fml::MessageLoop::GetCurrent().GetTaskRunner();
328 - (void)testFlutterViewOnlyCreateOnceInOneFrame {
329 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
331 flutter::TaskRunners runners(
self.name.UTF8String,
332 GetDefaultTaskRunner(),
333 GetDefaultTaskRunner(),
334 GetDefaultTaskRunner(),
335 GetDefaultTaskRunner());
338 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
339 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
342 flutterPlatformViewsController,
345 std::make_shared<fml::SyncSwitch>());
349 [flutterPlatformViewsController
351 withId:@"MockFlutterPlatformView"
355 [flutterPlatformViewsController
359 @"viewType" : @"MockFlutterPlatformView"
362 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
363 flutterPlatformViewsController.
flutterView = flutterView;
365 flutter::MutatorsStack stack;
367 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
368 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
369 stack.PushTransform(screenScaleMatrix);
371 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
372 stack.PushTransform(translateMatrix);
373 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
375 auto embeddedViewParams =
376 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
378 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
379 withParams:std::move(embeddedViewParams)];
383 [flutterPlatformViewsController
reset];
386 - (void)testCanCreatePlatformViewWithoutFlutterView {
387 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
389 flutter::TaskRunners runners(
self.name.UTF8String,
390 GetDefaultTaskRunner(),
391 GetDefaultTaskRunner(),
392 GetDefaultTaskRunner(),
393 GetDefaultTaskRunner());
396 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
397 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
400 flutterPlatformViewsController,
403 std::make_shared<fml::SyncSwitch>());
407 [flutterPlatformViewsController
409 withId:@"MockFlutterPlatformView"
413 [flutterPlatformViewsController
417 @"viewType" : @"MockFlutterPlatformView"
424 - (void)testChildClippingViewHitTests {
427 UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
428 [childClippingView addSubview:childView];
430 XCTAssertFalse([childClippingView pointInside:CGPointMake(50, 50) withEvent:nil]);
431 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 100) withEvent:nil]);
432 XCTAssertFalse([childClippingView pointInside:CGPointMake(100, 99) withEvent:nil]);
433 XCTAssertFalse([childClippingView pointInside:CGPointMake(201, 200) withEvent:nil]);
434 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 201) withEvent:nil]);
435 XCTAssertFalse([childClippingView pointInside:CGPointMake(99, 200) withEvent:nil]);
436 XCTAssertFalse([childClippingView pointInside:CGPointMake(200, 299) withEvent:nil]);
438 XCTAssertTrue([childClippingView pointInside:CGPointMake(150, 150) withEvent:nil]);
439 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 100) withEvent:nil]);
440 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 100) withEvent:nil]);
441 XCTAssertTrue([childClippingView pointInside:CGPointMake(100, 199) withEvent:nil]);
442 XCTAssertTrue([childClippingView pointInside:CGPointMake(199, 199) withEvent:nil]);
445 - (void)testReleasesBackdropFilterSubviewsOnChildClippingViewDealloc {
446 __weak NSMutableArray<UIVisualEffectView*>* weakBackdropFilterSubviews = nil;
447 __weak UIVisualEffectView* weakVisualEffectView1 = nil;
448 __weak UIVisualEffectView* weakVisualEffectView2 = nil;
452 UIVisualEffectView* visualEffectView1 = [[UIVisualEffectView alloc]
453 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
454 weakVisualEffectView1 = visualEffectView1;
458 visualEffectView:visualEffectView1];
463 UIVisualEffectView* visualEffectView2 = [[UIVisualEffectView alloc]
464 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
465 weakVisualEffectView2 = visualEffectView2;
469 visualEffectView:visualEffectView2];
473 XCTAssertNotNil(weakBackdropFilterSubviews);
476 XCTAssertNil(weakBackdropFilterSubviews);
477 XCTAssertNil(weakVisualEffectView1);
478 XCTAssertNil(weakVisualEffectView2);
481 - (void)testApplyBackdropFilter {
482 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
484 flutter::TaskRunners runners(
self.name.UTF8String,
485 GetDefaultTaskRunner(),
486 GetDefaultTaskRunner(),
487 GetDefaultTaskRunner(),
488 GetDefaultTaskRunner());
491 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
492 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
495 flutterPlatformViewsController,
498 std::make_shared<fml::SyncSwitch>());
502 [flutterPlatformViewsController
504 withId:@"MockFlutterPlatformView"
508 [flutterPlatformViewsController
512 @"viewType" : @"MockFlutterPlatformView"
518 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
519 flutterPlatformViewsController.
flutterView = flutterView;
521 flutter::MutatorsStack stack;
523 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
524 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
525 stack.PushTransform(screenScaleMatrix);
527 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
528 stack.PushBackdropFilter(filter,
529 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
531 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
532 screenScaleMatrix, flutter::DlSize(10, 10), stack);
534 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
535 withParams:std::move(embeddedViewParams)];
536 [flutterPlatformViewsController
542 [flutterView addSubview:childClippingView];
544 [flutterView setNeedsLayout];
545 [flutterView layoutIfNeeded];
548 NSUInteger numberOfExpectedVisualEffectView = 0;
549 for (UIView* subview in childClippingView.subviews) {
550 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
553 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
554 if ([
self validateOneVisualEffectView:subview
555 expectedFrame:CGRectMake(0, 0, 10, 10)
557 numberOfExpectedVisualEffectView++;
560 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
563 - (void)testApplyBackdropFilterWithCorrectFrame {
564 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
566 flutter::TaskRunners runners(
self.name.UTF8String,
567 GetDefaultTaskRunner(),
568 GetDefaultTaskRunner(),
569 GetDefaultTaskRunner(),
570 GetDefaultTaskRunner());
573 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
574 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
577 flutterPlatformViewsController,
580 std::make_shared<fml::SyncSwitch>());
584 [flutterPlatformViewsController
586 withId:@"MockFlutterPlatformView"
590 [flutterPlatformViewsController
594 @"viewType" : @"MockFlutterPlatformView"
600 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
601 flutterPlatformViewsController.
flutterView = flutterView;
603 flutter::MutatorsStack stack;
605 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
606 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
607 stack.PushTransform(screenScaleMatrix);
609 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
610 stack.PushBackdropFilter(filter,
611 flutter::DlRect::MakeXYWH(0, 0, screenScale * 8, screenScale * 8));
613 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
614 screenScaleMatrix, flutter::DlSize(5, 10), stack);
616 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
617 withParams:std::move(embeddedViewParams)];
618 [flutterPlatformViewsController
624 [flutterView addSubview:childClippingView];
626 [flutterView setNeedsLayout];
627 [flutterView layoutIfNeeded];
630 NSUInteger numberOfExpectedVisualEffectView = 0;
631 for (UIView* subview in childClippingView.subviews) {
632 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
635 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
636 if ([
self validateOneVisualEffectView:subview
637 expectedFrame:CGRectMake(0, 0, 5, 8)
639 numberOfExpectedVisualEffectView++;
642 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
645 - (void)testApplyMultipleBackdropFilters {
646 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
648 flutter::TaskRunners runners(
self.name.UTF8String,
649 GetDefaultTaskRunner(),
650 GetDefaultTaskRunner(),
651 GetDefaultTaskRunner(),
652 GetDefaultTaskRunner());
655 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
656 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
659 flutterPlatformViewsController,
662 std::make_shared<fml::SyncSwitch>());
666 [flutterPlatformViewsController
668 withId:@"MockFlutterPlatformView"
672 [flutterPlatformViewsController
676 @"viewType" : @"MockFlutterPlatformView"
682 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
683 flutterPlatformViewsController.
flutterView = flutterView;
685 flutter::MutatorsStack stack;
687 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
688 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
689 stack.PushTransform(screenScaleMatrix);
691 for (
int i = 0; i < 50; i++) {
692 auto filter = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
693 stack.PushBackdropFilter(filter,
694 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
697 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
698 screenScaleMatrix, flutter::DlSize(20, 20), stack);
700 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
701 withParams:std::move(embeddedViewParams)];
702 [flutterPlatformViewsController
708 [flutterView addSubview:childClippingView];
710 [flutterView setNeedsLayout];
711 [flutterView layoutIfNeeded];
713 NSUInteger numberOfExpectedVisualEffectView = 0;
714 for (UIView* subview in childClippingView.subviews) {
715 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
718 XCTAssertLessThan(numberOfExpectedVisualEffectView, 50u);
719 if ([
self validateOneVisualEffectView:subview
720 expectedFrame:CGRectMake(0, 0, 10, 10)
721 inputRadius:(CGFloat)numberOfExpectedVisualEffectView]) {
722 numberOfExpectedVisualEffectView++;
725 XCTAssertEqual(numberOfExpectedVisualEffectView, (NSUInteger)numberOfExpectedVisualEffectView);
728 - (void)testAddBackdropFilters {
729 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
731 flutter::TaskRunners runners(
self.name.UTF8String,
732 GetDefaultTaskRunner(),
733 GetDefaultTaskRunner(),
734 GetDefaultTaskRunner(),
735 GetDefaultTaskRunner());
738 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
739 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
742 flutterPlatformViewsController,
745 std::make_shared<fml::SyncSwitch>());
749 [flutterPlatformViewsController
751 withId:@"MockFlutterPlatformView"
755 [flutterPlatformViewsController
759 @"viewType" : @"MockFlutterPlatformView"
765 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
766 flutterPlatformViewsController.
flutterView = flutterView;
768 flutter::MutatorsStack stack;
770 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
771 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
772 stack.PushTransform(screenScaleMatrix);
774 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
775 stack.PushBackdropFilter(filter,
776 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
778 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
779 screenScaleMatrix, flutter::DlSize(10, 10), stack);
781 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
782 withParams:std::move(embeddedViewParams)];
783 [flutterPlatformViewsController
789 [flutterView addSubview:childClippingView];
791 [flutterView setNeedsLayout];
792 [flutterView layoutIfNeeded];
794 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
795 for (UIView* subview in childClippingView.subviews) {
796 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
799 XCTAssertLessThan(originalVisualEffectViews.count, 1u);
800 if ([
self validateOneVisualEffectView:subview
801 expectedFrame:CGRectMake(0, 0, 10, 10)
802 inputRadius:(CGFloat)5]) {
803 [originalVisualEffectViews addObject:subview];
806 XCTAssertEqual(originalVisualEffectViews.count, 1u);
811 flutter::MutatorsStack stack2;
813 stack2.PushTransform(screenScaleMatrix);
815 for (
int i = 0; i < 2; i++) {
816 stack2.PushBackdropFilter(filter,
817 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
820 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
821 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
823 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
824 withParams:std::move(embeddedViewParams)];
825 [flutterPlatformViewsController
829 [flutterView setNeedsLayout];
830 [flutterView layoutIfNeeded];
832 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
833 for (UIView* subview in childClippingView.subviews) {
834 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
837 XCTAssertLessThan(newVisualEffectViews.count, 2u);
839 if ([
self validateOneVisualEffectView:subview
840 expectedFrame:CGRectMake(0, 0, 10, 10)
841 inputRadius:(CGFloat)5]) {
842 [newVisualEffectViews addObject:subview];
845 XCTAssertEqual(newVisualEffectViews.count, 2u);
846 for (NSUInteger i = 0; i < originalVisualEffectViews.count; i++) {
847 UIView* originalView = originalVisualEffectViews[i];
848 UIView* newView = newVisualEffectViews[i];
850 XCTAssertEqual(originalView, newView);
851 id mockOrignalView = OCMPartialMock(originalView);
852 OCMReject([mockOrignalView removeFromSuperview]);
853 [mockOrignalView stopMocking];
857 - (void)testRemoveBackdropFilters {
858 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
860 flutter::TaskRunners runners(
self.name.UTF8String,
861 GetDefaultTaskRunner(),
862 GetDefaultTaskRunner(),
863 GetDefaultTaskRunner(),
864 GetDefaultTaskRunner());
867 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
868 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
871 flutterPlatformViewsController,
874 std::make_shared<fml::SyncSwitch>());
878 [flutterPlatformViewsController
880 withId:@"MockFlutterPlatformView"
884 [flutterPlatformViewsController
888 @"viewType" : @"MockFlutterPlatformView"
894 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
895 flutterPlatformViewsController.
flutterView = flutterView;
897 flutter::MutatorsStack stack;
899 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
900 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
901 stack.PushTransform(screenScaleMatrix);
903 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
904 for (
int i = 0; i < 5; i++) {
905 stack.PushBackdropFilter(filter,
906 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
909 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
910 screenScaleMatrix, flutter::DlSize(10, 10), stack);
912 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
913 withParams:std::move(embeddedViewParams)];
914 [flutterPlatformViewsController
920 [flutterView addSubview:childClippingView];
922 [flutterView setNeedsLayout];
923 [flutterView layoutIfNeeded];
925 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
926 for (UIView* subview in childClippingView.subviews) {
927 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
930 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
931 if ([
self validateOneVisualEffectView:subview
932 expectedFrame:CGRectMake(0, 0, 10, 10)
933 inputRadius:(CGFloat)5]) {
934 [originalVisualEffectViews addObject:subview];
940 flutter::MutatorsStack stack2;
942 stack2.PushTransform(screenScaleMatrix);
944 for (
int i = 0; i < 4; i++) {
945 stack2.PushBackdropFilter(filter,
946 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
949 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
950 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
952 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
953 withParams:std::move(embeddedViewParams)];
954 [flutterPlatformViewsController
958 [flutterView setNeedsLayout];
959 [flutterView layoutIfNeeded];
961 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
962 for (UIView* subview in childClippingView.subviews) {
963 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
966 XCTAssertLessThan(newVisualEffectViews.count, 4u);
967 if ([
self validateOneVisualEffectView:subview
968 expectedFrame:CGRectMake(0, 0, 10, 10)
969 inputRadius:(CGFloat)5]) {
970 [newVisualEffectViews addObject:subview];
973 XCTAssertEqual(newVisualEffectViews.count, 4u);
975 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
976 UIView* newView = newVisualEffectViews[i];
977 id mockNewView = OCMPartialMock(newView);
978 UIView* originalView = originalVisualEffectViews[i];
980 XCTAssertEqual(originalView, newView);
981 OCMReject([mockNewView removeFromSuperview]);
982 [mockNewView stopMocking];
987 for (
int i = 0; i < 5; i++) {
992 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
993 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
995 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
996 withParams:std::move(embeddedViewParams)];
997 [flutterPlatformViewsController
1001 [flutterView setNeedsLayout];
1002 [flutterView layoutIfNeeded];
1004 NSUInteger numberOfExpectedVisualEffectView = 0u;
1005 for (UIView* subview in childClippingView.subviews) {
1006 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1007 numberOfExpectedVisualEffectView++;
1010 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1013 - (void)testEditBackdropFilters {
1014 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1016 flutter::TaskRunners runners(
self.name.UTF8String,
1017 GetDefaultTaskRunner(),
1018 GetDefaultTaskRunner(),
1019 GetDefaultTaskRunner(),
1020 GetDefaultTaskRunner());
1023 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1024 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1027 flutterPlatformViewsController,
1030 std::make_shared<fml::SyncSwitch>());
1034 [flutterPlatformViewsController
1036 withId:@"MockFlutterPlatformView"
1040 [flutterPlatformViewsController
1044 @"viewType" : @"MockFlutterPlatformView"
1050 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1051 flutterPlatformViewsController.
flutterView = flutterView;
1053 flutter::MutatorsStack stack;
1055 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1056 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1057 stack.PushTransform(screenScaleMatrix);
1059 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1060 for (
int i = 0; i < 5; i++) {
1061 stack.PushBackdropFilter(filter,
1062 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1065 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1066 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1068 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1069 withParams:std::move(embeddedViewParams)];
1070 [flutterPlatformViewsController
1076 [flutterView addSubview:childClippingView];
1078 [flutterView setNeedsLayout];
1079 [flutterView layoutIfNeeded];
1081 NSMutableArray* originalVisualEffectViews = [[NSMutableArray alloc] init];
1082 for (UIView* subview in childClippingView.subviews) {
1083 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1086 XCTAssertLessThan(originalVisualEffectViews.count, 5u);
1087 if ([
self validateOneVisualEffectView:subview
1088 expectedFrame:CGRectMake(0, 0, 10, 10)
1089 inputRadius:(CGFloat)5]) {
1090 [originalVisualEffectViews addObject:subview];
1096 flutter::MutatorsStack stack2;
1098 stack2.PushTransform(screenScaleMatrix);
1100 for (
int i = 0; i < 5; i++) {
1102 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1104 stack2.PushBackdropFilter(
1105 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1109 stack2.PushBackdropFilter(filter,
1110 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1113 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1114 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1116 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1117 withParams:std::move(embeddedViewParams)];
1118 [flutterPlatformViewsController
1122 [flutterView setNeedsLayout];
1123 [flutterView layoutIfNeeded];
1125 NSMutableArray* newVisualEffectViews = [[NSMutableArray alloc] init];
1126 for (UIView* subview in childClippingView.subviews) {
1127 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1130 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1131 CGFloat expectInputRadius = 5;
1132 if (newVisualEffectViews.count == 3) {
1133 expectInputRadius = 2;
1135 if ([
self validateOneVisualEffectView:subview
1136 expectedFrame:CGRectMake(0, 0, 10, 10)
1137 inputRadius:expectInputRadius]) {
1138 [newVisualEffectViews addObject:subview];
1141 XCTAssertEqual(newVisualEffectViews.count, 5u);
1142 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1143 UIView* newView = newVisualEffectViews[i];
1144 id mockNewView = OCMPartialMock(newView);
1145 UIView* originalView = originalVisualEffectViews[i];
1147 XCTAssertEqual(originalView, newView);
1148 OCMReject([mockNewView removeFromSuperview]);
1149 [mockNewView stopMocking];
1151 [newVisualEffectViews removeAllObjects];
1155 for (
int i = 0; i < 5; i++) {
1159 for (
int i = 0; i < 5; i++) {
1161 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1162 stack2.PushBackdropFilter(
1163 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1167 stack2.PushBackdropFilter(filter,
1168 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1171 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1172 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1174 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1175 withParams:std::move(embeddedViewParams)];
1176 [flutterPlatformViewsController
1180 [flutterView setNeedsLayout];
1181 [flutterView layoutIfNeeded];
1183 for (UIView* subview in childClippingView.subviews) {
1184 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1187 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1188 CGFloat expectInputRadius = 5;
1189 if (newVisualEffectViews.count == 0) {
1190 expectInputRadius = 2;
1192 if ([
self validateOneVisualEffectView:subview
1193 expectedFrame:CGRectMake(0, 0, 10, 10)
1194 inputRadius:expectInputRadius]) {
1195 [newVisualEffectViews addObject:subview];
1198 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1199 UIView* newView = newVisualEffectViews[i];
1200 id mockNewView = OCMPartialMock(newView);
1201 UIView* originalView = originalVisualEffectViews[i];
1203 XCTAssertEqual(originalView, newView);
1204 OCMReject([mockNewView removeFromSuperview]);
1205 [mockNewView stopMocking];
1207 [newVisualEffectViews removeAllObjects];
1211 for (
int i = 0; i < 5; i++) {
1215 for (
int i = 0; i < 5; i++) {
1217 auto filter2 = flutter::DlBlurImageFilter::Make(2, 5, flutter::DlTileMode::kClamp);
1218 stack2.PushBackdropFilter(
1219 filter2, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1223 stack2.PushBackdropFilter(filter,
1224 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1227 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1228 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1230 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1231 withParams:std::move(embeddedViewParams)];
1232 [flutterPlatformViewsController
1236 [flutterView setNeedsLayout];
1237 [flutterView layoutIfNeeded];
1239 for (UIView* subview in childClippingView.subviews) {
1240 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1243 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1244 CGFloat expectInputRadius = 5;
1245 if (newVisualEffectViews.count == 4) {
1246 expectInputRadius = 2;
1248 if ([
self validateOneVisualEffectView:subview
1249 expectedFrame:CGRectMake(0, 0, 10, 10)
1250 inputRadius:expectInputRadius]) {
1251 [newVisualEffectViews addObject:subview];
1254 XCTAssertEqual(newVisualEffectViews.count, 5u);
1256 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1257 UIView* newView = newVisualEffectViews[i];
1258 id mockNewView = OCMPartialMock(newView);
1259 UIView* originalView = originalVisualEffectViews[i];
1261 XCTAssertEqual(originalView, newView);
1262 OCMReject([mockNewView removeFromSuperview]);
1263 [mockNewView stopMocking];
1265 [newVisualEffectViews removeAllObjects];
1269 for (
int i = 0; i < 5; i++) {
1273 for (
int i = 0; i < 5; i++) {
1274 auto filter2 = flutter::DlBlurImageFilter::Make(i, 2, flutter::DlTileMode::kClamp);
1276 stack2.PushBackdropFilter(filter2,
1277 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1280 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1281 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1283 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1284 withParams:std::move(embeddedViewParams)];
1285 [flutterPlatformViewsController
1289 [flutterView setNeedsLayout];
1290 [flutterView layoutIfNeeded];
1292 for (UIView* subview in childClippingView.subviews) {
1293 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1296 XCTAssertLessThan(newVisualEffectViews.count, 5u);
1297 if ([
self validateOneVisualEffectView:subview
1298 expectedFrame:CGRectMake(0, 0, 10, 10)
1299 inputRadius:(CGFloat)newVisualEffectViews.count]) {
1300 [newVisualEffectViews addObject:subview];
1303 XCTAssertEqual(newVisualEffectViews.count, 5u);
1305 for (NSUInteger i = 0; i < newVisualEffectViews.count; i++) {
1306 UIView* newView = newVisualEffectViews[i];
1307 id mockNewView = OCMPartialMock(newView);
1308 UIView* originalView = originalVisualEffectViews[i];
1310 XCTAssertEqual(originalView, newView);
1311 OCMReject([mockNewView removeFromSuperview]);
1312 [mockNewView stopMocking];
1314 [newVisualEffectViews removeAllObjects];
1317 - (void)testApplyBackdropFilterNotDlBlurImageFilter {
1318 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1320 flutter::TaskRunners runners(
self.name.UTF8String,
1321 GetDefaultTaskRunner(),
1322 GetDefaultTaskRunner(),
1323 GetDefaultTaskRunner(),
1324 GetDefaultTaskRunner());
1327 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1328 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1331 flutterPlatformViewsController,
1334 std::make_shared<fml::SyncSwitch>());
1338 [flutterPlatformViewsController
1340 withId:@"MockFlutterPlatformView"
1344 [flutterPlatformViewsController
1348 @"viewType" : @"MockFlutterPlatformView"
1354 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1355 flutterPlatformViewsController.
flutterView = flutterView;
1357 flutter::MutatorsStack stack;
1359 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1360 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1361 stack.PushTransform(screenScaleMatrix);
1363 auto dilateFilter = flutter::DlDilateImageFilter::Make(5, 2);
1364 stack.PushBackdropFilter(dilateFilter, flutter::DlRect());
1366 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1367 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1369 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1370 withParams:std::move(embeddedViewParams)];
1371 [flutterPlatformViewsController
1378 [flutterView addSubview:childClippingView];
1380 [flutterView setNeedsLayout];
1381 [flutterView layoutIfNeeded];
1383 NSUInteger numberOfExpectedVisualEffectView = 0;
1384 for (UIView* subview in childClippingView.subviews) {
1385 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1386 numberOfExpectedVisualEffectView++;
1389 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1393 flutter::MutatorsStack stack2;
1395 stack2.PushTransform(screenScaleMatrix);
1397 auto blurFilter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1399 for (
int i = 0; i < 5; i++) {
1401 stack2.PushBackdropFilter(
1402 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1406 stack2.PushBackdropFilter(blurFilter,
1407 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1410 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1411 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1413 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1414 withParams:std::move(embeddedViewParams)];
1415 [flutterPlatformViewsController
1419 [flutterView setNeedsLayout];
1420 [flutterView layoutIfNeeded];
1422 numberOfExpectedVisualEffectView = 0;
1423 for (UIView* subview in childClippingView.subviews) {
1424 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1427 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1428 if ([
self validateOneVisualEffectView:subview
1429 expectedFrame:CGRectMake(0, 0, 10, 10)
1430 inputRadius:(CGFloat)5]) {
1431 numberOfExpectedVisualEffectView++;
1434 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1438 for (
int i = 0; i < 5; i++) {
1442 for (
int i = 0; i < 5; i++) {
1444 stack2.PushBackdropFilter(
1445 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1449 stack2.PushBackdropFilter(blurFilter,
1450 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1453 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1454 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1456 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1457 withParams:std::move(embeddedViewParams)];
1458 [flutterPlatformViewsController
1462 [flutterView setNeedsLayout];
1463 [flutterView layoutIfNeeded];
1465 numberOfExpectedVisualEffectView = 0;
1466 for (UIView* subview in childClippingView.subviews) {
1467 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1470 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1471 if ([
self validateOneVisualEffectView:subview
1472 expectedFrame:CGRectMake(0, 0, 10, 10)
1473 inputRadius:(CGFloat)5]) {
1474 numberOfExpectedVisualEffectView++;
1477 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1481 for (
int i = 0; i < 5; i++) {
1485 for (
int i = 0; i < 5; i++) {
1487 stack2.PushBackdropFilter(
1488 dilateFilter, flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1492 stack2.PushBackdropFilter(blurFilter,
1493 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1496 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1497 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1499 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1500 withParams:std::move(embeddedViewParams)];
1501 [flutterPlatformViewsController
1505 [flutterView setNeedsLayout];
1506 [flutterView layoutIfNeeded];
1508 numberOfExpectedVisualEffectView = 0;
1509 for (UIView* subview in childClippingView.subviews) {
1510 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1513 XCTAssertLessThan(numberOfExpectedVisualEffectView, 4u);
1514 if ([
self validateOneVisualEffectView:subview
1515 expectedFrame:CGRectMake(0, 0, 10, 10)
1516 inputRadius:(CGFloat)5]) {
1517 numberOfExpectedVisualEffectView++;
1520 XCTAssertEqual(numberOfExpectedVisualEffectView, 4u);
1524 for (
int i = 0; i < 5; i++) {
1528 for (
int i = 0; i < 5; i++) {
1529 stack2.PushBackdropFilter(dilateFilter,
1530 flutter::DlRect::MakeXYWH(0, 0, screenScale * 10, screenScale * 10));
1533 embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1534 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
1536 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1537 withParams:std::move(embeddedViewParams)];
1538 [flutterPlatformViewsController
1542 [flutterView setNeedsLayout];
1543 [flutterView layoutIfNeeded];
1545 numberOfExpectedVisualEffectView = 0;
1546 for (UIView* subview in childClippingView.subviews) {
1547 if ([subview isKindOfClass:[UIVisualEffectView
class]]) {
1548 numberOfExpectedVisualEffectView++;
1551 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1554 - (void)testApplyBackdropFilterCorrectAPI {
1559 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1560 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1564 visualEffectView:visualEffectView];
1565 XCTAssertNotNil(platformViewFilter);
1568 - (void)testApplyBackdropFilterAPIChangedInvalidUIVisualEffectView {
1570 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc] init];
1574 visualEffectView:visualEffectView];
1575 XCTAssertNil(platformViewFilter);
1578 - (void)testApplyBackdropFilterAPIChangedNoGaussianBlurFilter {
1580 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1581 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1582 NSArray* subviews = editedUIVisualEffectView.subviews;
1583 for (UIView* view in subviews) {
1584 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1585 for (CIFilter* filter in view.layer.filters) {
1586 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1587 [filter setValue:@"notGaussianBlur" forKey:@"name"];
1597 visualEffectView:editedUIVisualEffectView];
1598 XCTAssertNil(platformViewFilter);
1601 - (void)testApplyBackdropFilterAPIChangedInvalidInputRadius {
1603 UIVisualEffectView* editedUIVisualEffectView = [[UIVisualEffectView alloc]
1604 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1605 NSArray* subviews = editedUIVisualEffectView.subviews;
1606 for (UIView* view in subviews) {
1607 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
1608 for (CIFilter* filter in view.layer.filters) {
1609 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"]) {
1610 [filter setValue:@"invalidInputRadius" forKey:@"inputRadius"];
1621 visualEffectView:editedUIVisualEffectView];
1622 XCTAssertNil(platformViewFilter);
1625 - (void)testBackdropFilterVisualEffectSubviewBackgroundColor {
1626 __weak UIVisualEffectView* weakVisualEffectView;
1629 UIVisualEffectView* visualEffectView = [[UIVisualEffectView alloc]
1630 initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
1631 weakVisualEffectView = visualEffectView;
1635 visualEffectView:visualEffectView];
1636 CGColorRef visualEffectSubviewBackgroundColor = nil;
1637 for (UIView* view in [platformViewFilter backdropFilterView].subviews) {
1638 if ([NSStringFromClass([view
class]) hasSuffix:
@"VisualEffectSubview"]) {
1639 visualEffectSubviewBackgroundColor = view.layer.backgroundColor;
1643 CGColorEqualToColor(visualEffectSubviewBackgroundColor, UIColor.clearColor.CGColor));
1645 XCTAssertNil(weakVisualEffectView);
1648 - (void)testCompositePlatformView {
1649 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1651 flutter::TaskRunners runners(
self.name.UTF8String,
1652 GetDefaultTaskRunner(),
1653 GetDefaultTaskRunner(),
1654 GetDefaultTaskRunner(),
1655 GetDefaultTaskRunner());
1658 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1659 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1662 flutterPlatformViewsController,
1665 std::make_shared<fml::SyncSwitch>());
1669 [flutterPlatformViewsController
1671 withId:@"MockFlutterPlatformView"
1675 [flutterPlatformViewsController
1679 @"viewType" : @"MockFlutterPlatformView"
1685 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1686 flutterPlatformViewsController.
flutterView = flutterView;
1688 flutter::MutatorsStack stack;
1690 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1691 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1692 stack.PushTransform(screenScaleMatrix);
1694 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
1695 stack.PushTransform(translateMatrix);
1696 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
1698 auto embeddedViewParams =
1699 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
1701 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1702 withParams:std::move(embeddedViewParams)];
1703 [flutterPlatformViewsController
1707 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1708 toView:flutterView];
1709 XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
1712 - (void)testBackdropFilterCorrectlyPushedAndReset {
1713 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1715 flutter::TaskRunners runners(
self.name.UTF8String,
1716 GetDefaultTaskRunner(),
1717 GetDefaultTaskRunner(),
1718 GetDefaultTaskRunner(),
1719 GetDefaultTaskRunner());
1722 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1723 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1726 flutterPlatformViewsController,
1729 std::make_shared<fml::SyncSwitch>());
1733 [flutterPlatformViewsController
1735 withId:@"MockFlutterPlatformView"
1739 [flutterPlatformViewsController
1743 @"viewType" : @"MockFlutterPlatformView"
1749 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
1750 flutterPlatformViewsController.
flutterView = flutterView;
1752 flutter::MutatorsStack stack;
1754 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1755 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1756 stack.PushTransform(screenScaleMatrix);
1758 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1759 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1761 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1762 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1763 withParams:std::move(embeddedViewParams)];
1765 auto filter = flutter::DlBlurImageFilter::Make(5, 2, flutter::DlTileMode::kClamp);
1766 [flutterPlatformViewsController
1767 pushFilterToVisitedPlatformViews:filter
1768 withRect:flutter::DlRect::MakeXYWH(0, 0, screenScale * 10,
1770 [flutterPlatformViewsController
1776 [flutterView addSubview:childClippingView];
1778 [flutterView setNeedsLayout];
1779 [flutterView layoutIfNeeded];
1782 NSUInteger numberOfExpectedVisualEffectView = 0;
1783 for (UIView* subview in childClippingView.subviews) {
1784 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1787 XCTAssertLessThan(numberOfExpectedVisualEffectView, 1u);
1788 if ([
self validateOneVisualEffectView:subview
1789 expectedFrame:CGRectMake(0, 0, 10, 10)
1791 numberOfExpectedVisualEffectView++;
1794 XCTAssertEqual(numberOfExpectedVisualEffectView, 1u);
1797 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
1798 screenScaleMatrix, flutter::DlSize(10, 10), stack);
1799 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(0, 0)];
1800 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1801 withParams:std::move(embeddedViewParams2)];
1802 [flutterPlatformViewsController
1808 [flutterView setNeedsLayout];
1809 [flutterView layoutIfNeeded];
1811 numberOfExpectedVisualEffectView = 0;
1812 for (UIView* subview in childClippingView.subviews) {
1813 if (![subview isKindOfClass:[UIVisualEffectView
class]]) {
1816 numberOfExpectedVisualEffectView++;
1818 XCTAssertEqual(numberOfExpectedVisualEffectView, 0u);
1821 - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
1822 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1824 flutter::TaskRunners runners(
self.name.UTF8String,
1825 GetDefaultTaskRunner(),
1826 GetDefaultTaskRunner(),
1827 GetDefaultTaskRunner(),
1828 GetDefaultTaskRunner());
1831 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1832 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1835 flutterPlatformViewsController,
1838 std::make_shared<fml::SyncSwitch>());
1842 [flutterPlatformViewsController
1844 withId:@"MockFlutterPlatformView"
1848 [flutterPlatformViewsController
1852 @"viewType" : @"MockFlutterPlatformView"
1858 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
1859 flutterPlatformViewsController.
flutterView = flutterView;
1861 flutter::MutatorsStack stack;
1863 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1864 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1865 stack.PushTransform(screenScaleMatrix);
1867 flutter::DlMatrix rotateMatrix = flutter::DlMatrix::MakeRotationZ(flutter::DlDegrees(10));
1868 stack.PushTransform(rotateMatrix);
1869 flutter::DlMatrix finalMatrix = screenScaleMatrix * rotateMatrix;
1871 auto embeddedViewParams =
1872 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
1874 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1875 withParams:std::move(embeddedViewParams)];
1876 [flutterPlatformViewsController
1880 CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
1881 toView:flutterView];
1887 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x),
1889 XCTAssertLessThan(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y),
1892 fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width),
1895 fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
1899 - (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView {
1900 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1902 flutter::TaskRunners runners(
self.name.UTF8String,
1903 GetDefaultTaskRunner(),
1904 GetDefaultTaskRunner(),
1905 GetDefaultTaskRunner(),
1906 GetDefaultTaskRunner());
1909 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1910 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1913 flutterPlatformViewsController,
1916 std::make_shared<fml::SyncSwitch>());
1920 [flutterPlatformViewsController
1922 withId:@"MockFlutterPlatformView"
1926 [flutterPlatformViewsController
1930 @"viewType" : @"MockFlutterPlatformView"
1936 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
1937 flutterPlatformViewsController.
flutterView = flutterView;
1939 flutter::MutatorsStack stack;
1941 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
1942 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
1943 stack.PushTransform(screenScaleMatrix);
1944 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
1946 stack.PushTransform(translateMatrix);
1948 flutter::DlRect rect = flutter::DlRect::MakeXYWH(0, 0, 25, 25);
1949 stack.PushClipRect(rect);
1952 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(-1, -1, 25, 25);
1953 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
1954 stack.PushClipRRect(rrect);
1956 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
1957 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
1959 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
1960 withParams:std::move(embeddedViewParams)];
1961 [flutterPlatformViewsController
1968 [flutterView addSubview:childClippingView];
1970 [flutterView setNeedsLayout];
1971 [flutterView layoutIfNeeded];
1972 XCTAssertNil(childClippingView.maskView);
1975 - (void)testClipRRectOnlyHasCornersInterceptWithPlatformViewShouldAddMaskView {
1976 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
1978 flutter::TaskRunners runners(
self.name.UTF8String,
1979 GetDefaultTaskRunner(),
1980 GetDefaultTaskRunner(),
1981 GetDefaultTaskRunner(),
1982 GetDefaultTaskRunner());
1985 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
1986 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
1989 flutterPlatformViewsController,
1992 std::make_shared<fml::SyncSwitch>());
1996 [flutterPlatformViewsController
1998 withId:@"MockFlutterPlatformView"
2002 [flutterPlatformViewsController
2006 @"viewType" : @"MockFlutterPlatformView"
2012 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
2013 flutterPlatformViewsController.
flutterView = flutterView;
2015 flutter::MutatorsStack stack;
2017 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2018 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2019 stack.PushTransform(screenScaleMatrix);
2020 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({5, 5});
2022 stack.PushTransform(translateMatrix);
2026 flutter::DlRect rect_for_rrect = flutter::DlRect::MakeXYWH(0, 0, 10, 10);
2027 flutter::DlRoundRect rrect = flutter::DlRoundRect::MakeRectXY(rect_for_rrect, 1, 1);
2028 stack.PushClipRRect(rrect);
2030 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2031 screenScaleMatrix * translateMatrix, flutter::DlSize(5, 5), stack);
2033 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2034 withParams:std::move(embeddedViewParams)];
2035 [flutterPlatformViewsController
2042 [flutterView addSubview:childClippingView];
2044 [flutterView setNeedsLayout];
2045 [flutterView layoutIfNeeded];
2047 XCTAssertNotNil(childClippingView.maskView);
2050 - (void)testClipRect {
2051 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2053 flutter::TaskRunners runners(
self.name.UTF8String,
2054 GetDefaultTaskRunner(),
2055 GetDefaultTaskRunner(),
2056 GetDefaultTaskRunner(),
2057 GetDefaultTaskRunner());
2060 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2061 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2064 flutterPlatformViewsController,
2067 std::make_shared<fml::SyncSwitch>());
2071 [flutterPlatformViewsController
2073 withId:@"MockFlutterPlatformView"
2077 [flutterPlatformViewsController
2081 @"viewType" : @"MockFlutterPlatformView"
2087 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2088 flutterPlatformViewsController.
flutterView = flutterView;
2090 flutter::MutatorsStack stack;
2092 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2093 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2094 stack.PushTransform(screenScaleMatrix);
2096 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2097 stack.PushClipRect(rect);
2099 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2100 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2102 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2103 withParams:std::move(embeddedViewParams)];
2104 [flutterPlatformViewsController
2111 [flutterView addSubview:childClippingView];
2113 [flutterView setNeedsLayout];
2114 [flutterView layoutIfNeeded];
2116 CGRect insideClipping = CGRectMake(2, 2, 3, 3);
2117 for (
int i = 0; i < 10; i++) {
2118 for (
int j = 0; j < 10; j++) {
2119 CGPoint point = CGPointMake(i, j);
2120 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2121 if (CGRectContainsPoint(insideClipping, point)) {
2122 XCTAssertEqual(alpha, 255);
2124 XCTAssertEqual(alpha, 0);
2130 - (void)testClipRect_multipleClips {
2131 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2133 flutter::TaskRunners runners(
self.name.UTF8String,
2134 GetDefaultTaskRunner(),
2135 GetDefaultTaskRunner(),
2136 GetDefaultTaskRunner(),
2137 GetDefaultTaskRunner());
2140 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2141 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2144 flutterPlatformViewsController,
2147 std::make_shared<fml::SyncSwitch>());
2151 [flutterPlatformViewsController
2153 withId:@"MockFlutterPlatformView"
2157 [flutterPlatformViewsController
2161 @"viewType" : @"MockFlutterPlatformView"
2167 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2168 flutterPlatformViewsController.
flutterView = flutterView;
2170 flutter::MutatorsStack stack;
2172 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2173 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2174 stack.PushTransform(screenScaleMatrix);
2176 flutter::DlRect rect1 = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
2177 stack.PushClipRect(rect1);
2179 flutter::DlRect rect2 = flutter::DlRect::MakeXYWH(3, 3, 3, 3);
2180 stack.PushClipRect(rect2);
2182 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2183 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2185 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2186 withParams:std::move(embeddedViewParams)];
2187 [flutterPlatformViewsController
2194 [flutterView addSubview:childClippingView];
2196 [flutterView setNeedsLayout];
2197 [flutterView layoutIfNeeded];
2216 CGRect insideClipping = CGRectMake(3, 3, 2, 2);
2217 for (
int i = 0; i < 10; i++) {
2218 for (
int j = 0; j < 10; j++) {
2219 CGPoint point = CGPointMake(i, j);
2220 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2221 if (CGRectContainsPoint(insideClipping, point)) {
2222 XCTAssertEqual(alpha, 255);
2224 XCTAssertEqual(alpha, 0);
2230 - (void)testClipRRect {
2231 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2233 flutter::TaskRunners runners(
self.name.UTF8String,
2234 GetDefaultTaskRunner(),
2235 GetDefaultTaskRunner(),
2236 GetDefaultTaskRunner(),
2237 GetDefaultTaskRunner());
2240 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2241 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2244 flutterPlatformViewsController,
2247 std::make_shared<fml::SyncSwitch>());
2251 [flutterPlatformViewsController
2253 withId:@"MockFlutterPlatformView"
2257 [flutterPlatformViewsController
2261 @"viewType" : @"MockFlutterPlatformView"
2267 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2268 flutterPlatformViewsController.
flutterView = flutterView;
2270 flutter::MutatorsStack stack;
2272 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2273 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2274 stack.PushTransform(screenScaleMatrix);
2276 flutter::DlRoundRect rrect =
2277 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2278 stack.PushClipRRect(rrect);
2280 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2281 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2283 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2284 withParams:std::move(embeddedViewParams)];
2285 [flutterPlatformViewsController
2292 [flutterView addSubview:childClippingView];
2294 [flutterView setNeedsLayout];
2295 [flutterView layoutIfNeeded];
2316 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2317 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2318 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2319 for (
int i = 0; i < 10; i++) {
2320 for (
int j = 0; j < 10; j++) {
2321 CGPoint point = CGPointMake(i, j);
2322 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2323 if (CGRectContainsPoint(innerClipping1, point) ||
2324 CGRectContainsPoint(innerClipping2, point)) {
2326 XCTAssertEqual(alpha, 255);
2327 }
else if (CGRectContainsPoint(outterClipping, point)) {
2329 XCTAssert(0 < alpha && alpha < 255);
2332 XCTAssertEqual(alpha, 0);
2338 - (void)testClipRRect_multipleClips {
2339 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2341 flutter::TaskRunners runners(
self.name.UTF8String,
2342 GetDefaultTaskRunner(),
2343 GetDefaultTaskRunner(),
2344 GetDefaultTaskRunner(),
2345 GetDefaultTaskRunner());
2348 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2349 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2352 flutterPlatformViewsController,
2355 std::make_shared<fml::SyncSwitch>());
2359 [flutterPlatformViewsController
2361 withId:@"MockFlutterPlatformView"
2365 [flutterPlatformViewsController
2369 @"viewType" : @"MockFlutterPlatformView"
2375 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2376 flutterPlatformViewsController.
flutterView = flutterView;
2378 flutter::MutatorsStack stack;
2380 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2381 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2382 stack.PushTransform(screenScaleMatrix);
2384 flutter::DlRoundRect rrect =
2385 flutter::DlRoundRect::MakeRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2386 stack.PushClipRRect(rrect);
2388 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2389 stack.PushClipRect(rect);
2391 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2392 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2394 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2395 withParams:std::move(embeddedViewParams)];
2396 [flutterPlatformViewsController
2403 [flutterView addSubview:childClippingView];
2405 [flutterView setNeedsLayout];
2406 [flutterView layoutIfNeeded];
2427 CGRect clipping = CGRectMake(4, 2, 4, 6);
2428 for (
int i = 0; i < 10; i++) {
2429 for (
int j = 0; j < 10; j++) {
2430 CGPoint point = CGPointMake(i, j);
2431 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2432 if (i == 7 && (j == 2 || j == 7)) {
2434 XCTAssert(0 < alpha && alpha < 255);
2437 (i == 4 && j >= 2 && j <= 7) ||
2439 (i == 7 && j >= 2 && j <= 7) ||
2441 (j == 2 && i >= 4 && i <= 7) ||
2443 (j == 7 && i >= 4 && i <= 7)) {
2446 XCTAssert(alpha > 127);
2447 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2448 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2451 XCTAssert(alpha < 127);
2452 }
else if (CGRectContainsPoint(clipping, point)) {
2454 XCTAssertEqual(alpha, 255);
2457 XCTAssertEqual(alpha, 0);
2463 - (void)testClipPath {
2464 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2466 flutter::TaskRunners runners(
self.name.UTF8String,
2467 GetDefaultTaskRunner(),
2468 GetDefaultTaskRunner(),
2469 GetDefaultTaskRunner(),
2470 GetDefaultTaskRunner());
2473 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2474 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2477 flutterPlatformViewsController,
2480 std::make_shared<fml::SyncSwitch>());
2484 [flutterPlatformViewsController
2486 withId:@"MockFlutterPlatformView"
2490 [flutterPlatformViewsController
2494 @"viewType" : @"MockFlutterPlatformView"
2500 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2501 flutterPlatformViewsController.
flutterView = flutterView;
2503 flutter::MutatorsStack stack;
2505 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2506 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2507 stack.PushTransform(screenScaleMatrix);
2509 flutter::DlPath path =
2510 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2511 stack.PushClipPath(path);
2513 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2514 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2516 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2517 withParams:std::move(embeddedViewParams)];
2518 [flutterPlatformViewsController
2525 [flutterView addSubview:childClippingView];
2527 [flutterView setNeedsLayout];
2528 [flutterView layoutIfNeeded];
2549 CGRect innerClipping1 = CGRectMake(3, 2, 4, 6);
2550 CGRect innerClipping2 = CGRectMake(2, 3, 6, 4);
2551 CGRect outterClipping = CGRectMake(2, 2, 6, 6);
2552 for (
int i = 0; i < 10; i++) {
2553 for (
int j = 0; j < 10; j++) {
2554 CGPoint point = CGPointMake(i, j);
2555 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2556 if (CGRectContainsPoint(innerClipping1, point) ||
2557 CGRectContainsPoint(innerClipping2, point)) {
2559 XCTAssertEqual(alpha, 255);
2560 }
else if (CGRectContainsPoint(outterClipping, point)) {
2562 XCTAssert(0 < alpha && alpha < 255);
2565 XCTAssertEqual(alpha, 0);
2571 - (void)testClipPath_multipleClips {
2572 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2574 flutter::TaskRunners runners(
self.name.UTF8String,
2575 GetDefaultTaskRunner(),
2576 GetDefaultTaskRunner(),
2577 GetDefaultTaskRunner(),
2578 GetDefaultTaskRunner());
2581 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2582 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2585 flutterPlatformViewsController,
2588 std::make_shared<fml::SyncSwitch>());
2592 [flutterPlatformViewsController
2594 withId:@"MockFlutterPlatformView"
2598 [flutterPlatformViewsController
2602 @"viewType" : @"MockFlutterPlatformView"
2608 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
2609 flutterPlatformViewsController.
flutterView = flutterView;
2611 flutter::MutatorsStack stack;
2613 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
2614 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
2615 stack.PushTransform(screenScaleMatrix);
2617 flutter::DlPath path =
2618 flutter::DlPath::MakeRoundRectXY(flutter::DlRect::MakeXYWH(2, 2, 6, 6), 1, 1);
2619 stack.PushClipPath(path);
2621 flutter::DlRect rect = flutter::DlRect::MakeXYWH(4, 2, 6, 6);
2622 stack.PushClipRect(rect);
2624 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
2625 screenScaleMatrix, flutter::DlSize(10, 10), stack);
2627 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
2628 withParams:std::move(embeddedViewParams)];
2629 [flutterPlatformViewsController
2636 [flutterView addSubview:childClippingView];
2638 [flutterView setNeedsLayout];
2639 [flutterView layoutIfNeeded];
2660 CGRect clipping = CGRectMake(4, 2, 4, 6);
2661 for (
int i = 0; i < 10; i++) {
2662 for (
int j = 0; j < 10; j++) {
2663 CGPoint point = CGPointMake(i, j);
2664 int alpha = [
self alphaOfPoint:CGPointMake(i, j) onView:flutterView];
2665 if (i == 7 && (j == 2 || j == 7)) {
2667 XCTAssert(0 < alpha && alpha < 255);
2670 (i == 4 && j >= 2 && j <= 7) ||
2672 (i == 7 && j >= 2 && j <= 7) ||
2674 (j == 2 && i >= 4 && i <= 7) ||
2676 (j == 7 && i >= 4 && i <= 7)) {
2679 XCTAssert(alpha > 127);
2680 }
else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) ||
2681 (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) {
2684 XCTAssert(alpha < 127);
2685 }
else if (CGRectContainsPoint(clipping, point)) {
2687 XCTAssertEqual(alpha, 255);
2690 XCTAssertEqual(alpha, 0);
2696 - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
2697 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2699 flutter::TaskRunners runners(
self.name.UTF8String,
2700 GetDefaultTaskRunner(),
2701 GetDefaultTaskRunner(),
2702 GetDefaultTaskRunner(),
2703 GetDefaultTaskRunner());
2706 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2707 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2710 flutterPlatformViewsController,
2713 std::make_shared<fml::SyncSwitch>());
2717 [flutterPlatformViewsController
2719 withId:@"MockFlutterPlatformView"
2723 [flutterPlatformViewsController
2727 @"viewType" : @"MockFlutterPlatformView"
2735 while (touchInteceptorView != nil &&
2737 touchInteceptorView = touchInteceptorView.superview;
2739 XCTAssertNotNil(touchInteceptorView);
2742 UIGestureRecognizer* forwardGectureRecognizer = nil;
2743 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2745 forwardGectureRecognizer = gestureRecognizer;
2751 NSSet* touches1 = [[NSSet alloc] init];
2752 id event1 = OCMClassMock([UIEvent
class]);
2754 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2755 OCMReject([flutterViewController touchesBegan:touches1 withEvent:event1]);
2758 NSSet* touches2 = [[NSSet alloc] init];
2759 id event2 = OCMClassMock([UIEvent
class]);
2761 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
2762 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
2765 - (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled {
2766 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2768 flutter::TaskRunners runners(
self.name.UTF8String,
2769 GetDefaultTaskRunner(),
2770 GetDefaultTaskRunner(),
2771 GetDefaultTaskRunner(),
2772 GetDefaultTaskRunner());
2775 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2776 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2779 flutterPlatformViewsController,
2782 std::make_shared<fml::SyncSwitch>());
2786 [flutterPlatformViewsController
2788 withId:@"MockFlutterPlatformView"
2792 [flutterPlatformViewsController
2796 @"viewType" : @"MockFlutterPlatformView"
2804 while (touchInteceptorView != nil &&
2806 touchInteceptorView = touchInteceptorView.superview;
2808 XCTAssertNotNil(touchInteceptorView);
2811 UIGestureRecognizer* forwardGectureRecognizer = nil;
2812 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2814 forwardGectureRecognizer = gestureRecognizer;
2823 NSSet* touches1 = [[NSSet alloc] init];
2824 id event1 = OCMClassMock([UIEvent
class]);
2825 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2826 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2831 NSSet* touches2 = [[NSSet alloc] init];
2832 id event2 = OCMClassMock([UIEvent
class]);
2833 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2834 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2836 NSSet* touches3 = [[NSSet alloc] init];
2837 id event3 = OCMClassMock([UIEvent
class]);
2838 [forwardGectureRecognizer touchesEnded:touches3 withEvent:event3];
2839 OCMVerify([flutterViewController touchesEnded:touches3 withEvent:event3]);
2842 NSSet* touches4 = [[NSSet alloc] init];
2843 id event4 = OCMClassMock([UIEvent
class]);
2844 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2845 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2847 NSSet* touches5 = [[NSSet alloc] init];
2848 id event5 = OCMClassMock([UIEvent
class]);
2849 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2850 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2857 NSSet* touches1 = [[NSSet alloc] init];
2858 id event1 = OCMClassMock([UIEvent
class]);
2859 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2860 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2865 NSSet* touches2 = [[NSSet alloc] init];
2866 id event2 = OCMClassMock([UIEvent
class]);
2867 [forwardGectureRecognizer touchesMoved:touches2 withEvent:event2];
2868 OCMVerify([flutterViewController touchesMoved:touches2 withEvent:event2]);
2870 NSSet* touches3 = [[NSSet alloc] init];
2871 id event3 = OCMClassMock([UIEvent
class]);
2872 [forwardGectureRecognizer touchesCancelled:touches3 withEvent:event3];
2873 OCMVerify([flutterViewController forceTouchesCancelled:touches3]);
2876 NSSet* touches4 = [[NSSet alloc] init];
2877 id event4 = OCMClassMock([UIEvent
class]);
2878 [forwardGectureRecognizer touchesBegan:touches4 withEvent:event4];
2879 OCMReject([flutterViewController touchesBegan:touches4 withEvent:event4]);
2881 NSSet* touches5 = [[NSSet alloc] init];
2882 id event5 = OCMClassMock([UIEvent
class]);
2883 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2884 OCMReject([flutterViewController touchesEnded:touches5 withEvent:event5]);
2887 [flutterPlatformViewsController
reset];
2891 testSetFlutterViewControllerInTheMiddleOfTouchEventAllowsTheNewControllerToHandleSecondTouchSequence {
2892 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2894 flutter::TaskRunners runners(
self.name.UTF8String,
2895 GetDefaultTaskRunner(),
2896 GetDefaultTaskRunner(),
2897 GetDefaultTaskRunner(),
2898 GetDefaultTaskRunner());
2901 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
2902 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2905 flutterPlatformViewsController,
2908 std::make_shared<fml::SyncSwitch>());
2912 [flutterPlatformViewsController
2914 withId:@"MockFlutterPlatformView"
2918 [flutterPlatformViewsController
2922 @"viewType" : @"MockFlutterPlatformView"
2930 while (touchInteceptorView != nil &&
2932 touchInteceptorView = touchInteceptorView.superview;
2934 XCTAssertNotNil(touchInteceptorView);
2937 UIGestureRecognizer* forwardGectureRecognizer = nil;
2938 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
2940 forwardGectureRecognizer = gestureRecognizer;
2948 NSSet* touches1 = [NSSet setWithObject:@1];
2949 id event1 = OCMClassMock([UIEvent
class]);
2950 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
2951 OCMVerify([flutterViewController touchesBegan:touches1 withEvent:event1]);
2958 NSSet* touches2 = [NSSet setWithObject:@1];
2959 id event2 = OCMClassMock([UIEvent
class]);
2960 [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
2961 OCMVerify([flutterViewController touchesBegan:touches2 withEvent:event2]);
2962 OCMReject([flutterViewController2 touchesBegan:touches2 withEvent:event2]);
2964 NSSet* touches3 = [NSSet setWithObject:@1];
2965 id event3 = OCMClassMock([UIEvent
class]);
2966 [forwardGectureRecognizer touchesMoved:touches3 withEvent:event3];
2967 OCMVerify([flutterViewController touchesMoved:touches3 withEvent:event3]);
2968 OCMReject([flutterViewController2 touchesMoved:touches3 withEvent:event3]);
2970 NSSet* touches4 = [NSSet setWithObject:@1];
2971 id event4 = OCMClassMock([UIEvent
class]);
2972 [forwardGectureRecognizer touchesEnded:touches4 withEvent:event4];
2973 OCMVerify([flutterViewController touchesEnded:touches4 withEvent:event4]);
2974 OCMReject([flutterViewController2 touchesEnded:touches4 withEvent:event4]);
2976 NSSet* touches5 = [NSSet setWithObject:@1];
2977 id event5 = OCMClassMock([UIEvent
class]);
2978 [forwardGectureRecognizer touchesEnded:touches5 withEvent:event5];
2979 OCMVerify([flutterViewController touchesEnded:touches5 withEvent:event5]);
2980 OCMReject([flutterViewController2 touchesEnded:touches5 withEvent:event5]);
2984 NSSet* touches6 = [NSSet setWithObject:@1];
2985 id event6 = OCMClassMock([UIEvent
class]);
2986 [forwardGectureRecognizer touchesBegan:touches6 withEvent:event6];
2987 OCMVerify([flutterViewController2 touchesBegan:touches6 withEvent:event6]);
2988 OCMReject([flutterViewController touchesBegan:touches6 withEvent:event6]);
2991 NSSet* touches7 = [NSSet setWithObject:@1];
2992 id event7 = OCMClassMock([UIEvent
class]);
2993 [forwardGectureRecognizer touchesMoved:touches7 withEvent:event7];
2994 OCMVerify([flutterViewController2 touchesMoved:touches7 withEvent:event7]);
2995 OCMReject([flutterViewController touchesMoved:touches7 withEvent:event7]);
2997 NSSet* touches8 = [NSSet setWithObject:@1];
2998 id event8 = OCMClassMock([UIEvent
class]);
2999 [forwardGectureRecognizer touchesEnded:touches8 withEvent:event8];
3000 OCMVerify([flutterViewController2 touchesEnded:touches8 withEvent:event8]);
3001 OCMReject([flutterViewController touchesEnded:touches8 withEvent:event8]);
3003 [flutterPlatformViewsController
reset];
3006 - (void)testFlutterPlatformViewTouchesCancelledEventAreForcedToBeCancelled {
3007 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3009 flutter::TaskRunners runners(
self.name.UTF8String,
3010 GetDefaultTaskRunner(),
3011 GetDefaultTaskRunner(),
3012 GetDefaultTaskRunner(),
3013 GetDefaultTaskRunner());
3016 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3017 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3020 flutterPlatformViewsController,
3023 std::make_shared<fml::SyncSwitch>());
3027 [flutterPlatformViewsController
3029 withId:@"MockFlutterPlatformView"
3033 [flutterPlatformViewsController
3037 @"viewType" : @"MockFlutterPlatformView"
3045 while (touchInteceptorView != nil &&
3047 touchInteceptorView = touchInteceptorView.superview;
3049 XCTAssertNotNil(touchInteceptorView);
3052 UIGestureRecognizer* forwardGectureRecognizer = nil;
3053 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3055 forwardGectureRecognizer = gestureRecognizer;
3062 NSSet* touches1 = [NSSet setWithObject:@1];
3063 id event1 = OCMClassMock([UIEvent
class]);
3064 [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1];
3066 [forwardGectureRecognizer touchesCancelled:touches1 withEvent:event1];
3067 OCMVerify([flutterViewController forceTouchesCancelled:touches1]);
3069 [flutterPlatformViewsController
reset];
3072 - (void)testFlutterPlatformViewTouchesEndedOrTouchesCancelledEventDoesNotFailTheGestureRecognizer {
3073 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3075 flutter::TaskRunners runners(
self.name.UTF8String,
3076 GetDefaultTaskRunner(),
3077 GetDefaultTaskRunner(),
3078 GetDefaultTaskRunner(),
3079 GetDefaultTaskRunner());
3082 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3083 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3086 flutterPlatformViewsController,
3089 std::make_shared<fml::SyncSwitch>());
3093 [flutterPlatformViewsController
3095 withId:@"MockFlutterPlatformView"
3099 [flutterPlatformViewsController
3103 @"viewType" : @"MockFlutterPlatformView"
3111 while (touchInteceptorView != nil &&
3113 touchInteceptorView = touchInteceptorView.superview;
3115 XCTAssertNotNil(touchInteceptorView);
3118 __block UIGestureRecognizer* forwardGestureRecognizer = nil;
3119 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3121 forwardGestureRecognizer = gestureRecognizer;
3128 NSSet* touches1 = [NSSet setWithObject:@1];
3129 id event1 = OCMClassMock([UIEvent
class]);
3130 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3131 @"Forwarding gesture recognizer must start with possible state.");
3132 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3133 [forwardGestureRecognizer touchesEnded:touches1 withEvent:event1];
3134 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3135 @"Forwarding gesture recognizer must end with failed state.");
3137 XCTestExpectation* touchEndedExpectation =
3138 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3139 dispatch_async(dispatch_get_main_queue(), ^{
3141 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3142 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3143 forwardGestureRecognizer = gestureRecognizer;
3147 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3148 @"Forwarding gesture recognizer must be reset to possible state.");
3149 [touchEndedExpectation fulfill];
3151 [
self waitForExpectationsWithTimeout:30 handler:nil];
3153 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3154 @"Forwarding gesture recognizer must start with possible state.");
3155 [forwardGestureRecognizer touchesBegan:touches1 withEvent:event1];
3156 [forwardGestureRecognizer touchesCancelled:touches1 withEvent:event1];
3157 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStateFailed,
3158 @"Forwarding gesture recognizer must end with failed state.");
3159 XCTestExpectation* touchCancelledExpectation =
3160 [
self expectationWithDescription:@"Wait for gesture recognizer's state change."];
3161 dispatch_async(dispatch_get_main_queue(), ^{
3163 for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) {
3164 if ([gestureRecognizer isKindOfClass:[ForwardingGestureRecognizer class]]) {
3165 forwardGestureRecognizer = gestureRecognizer;
3169 XCTAssert(forwardGestureRecognizer.state == UIGestureRecognizerStatePossible,
3170 @"Forwarding gesture recognizer must be reset to possible state.");
3171 [touchCancelledExpectation fulfill];
3173 [
self waitForExpectationsWithTimeout:30 handler:nil];
3175 [flutterPlatformViewsController reset];
3179 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWebView {
3180 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3182 flutter::TaskRunners runners(
self.name.UTF8String,
3183 GetDefaultTaskRunner(),
3184 GetDefaultTaskRunner(),
3185 GetDefaultTaskRunner(),
3186 GetDefaultTaskRunner());
3189 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3190 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3193 flutterPlatformViewsController,
3196 std::make_shared<fml::SyncSwitch>());
3200 [flutterPlatformViewsController
3206 [flutterPlatformViewsController
3209 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3216 while (touchInteceptorView != nil &&
3218 touchInteceptorView = touchInteceptorView.superview;
3220 XCTAssertNotNil(touchInteceptorView);
3222 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3223 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3224 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3231 BOOL shouldReAddDelayingRecognizer = NO;
3232 if (@available(iOS 26.0, *)) {
3235 }
else if (@available(iOS 18.2, *)) {
3236 shouldReAddDelayingRecognizer = YES;
3238 if (shouldReAddDelayingRecognizer) {
3240 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3241 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3243 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3244 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3249 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldRemoveAndAddBackDelayingRecognizerForWrapperWebView {
3250 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3252 flutter::TaskRunners runners(
self.name.UTF8String,
3253 GetDefaultTaskRunner(),
3254 GetDefaultTaskRunner(),
3255 GetDefaultTaskRunner(),
3256 GetDefaultTaskRunner());
3259 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3260 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3263 flutterPlatformViewsController,
3266 std::make_shared<fml::SyncSwitch>());
3270 [flutterPlatformViewsController
3272 withId:@"MockWrapperWebView"
3276 [flutterPlatformViewsController
3279 arguments:@{@"id" : @2, @"viewType" : @"MockWrapperWebView"}]
3286 while (touchInteceptorView != nil &&
3288 touchInteceptorView = touchInteceptorView.superview;
3290 XCTAssertNotNil(touchInteceptorView);
3292 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3293 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3294 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3301 BOOL shouldReAddDelayingRecognizer = NO;
3302 if (@available(iOS 26.0, *)) {
3305 }
else if (@available(iOS 18.2, *)) {
3306 shouldReAddDelayingRecognizer = YES;
3308 if (shouldReAddDelayingRecognizer) {
3310 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], forwardingRecognizer);
3311 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], delayingRecognizer);
3313 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3314 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3319 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNestedWrapperWebView {
3320 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3322 flutter::TaskRunners runners(
self.name.UTF8String,
3323 GetDefaultTaskRunner(),
3324 GetDefaultTaskRunner(),
3325 GetDefaultTaskRunner(),
3326 GetDefaultTaskRunner());
3329 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3330 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3333 flutterPlatformViewsController,
3336 std::make_shared<fml::SyncSwitch>());
3340 [flutterPlatformViewsController
3342 withId:@"MockNestedWrapperWebView"
3346 [flutterPlatformViewsController
3350 @"viewType" : @"MockNestedWrapperWebView"
3358 while (touchInteceptorView != nil &&
3360 touchInteceptorView = touchInteceptorView.superview;
3362 XCTAssertNotNil(touchInteceptorView);
3364 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3365 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3366 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3373 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3374 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3378 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldNotRemoveAndAddBackDelayingRecognizerForNonWebView {
3379 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3381 flutter::TaskRunners runners(
self.name.UTF8String,
3382 GetDefaultTaskRunner(),
3383 GetDefaultTaskRunner(),
3384 GetDefaultTaskRunner(),
3385 GetDefaultTaskRunner());
3388 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3389 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3392 flutterPlatformViewsController,
3395 std::make_shared<fml::SyncSwitch>());
3399 [flutterPlatformViewsController
3401 withId:@"MockFlutterPlatformView"
3405 [flutterPlatformViewsController
3409 @"viewType" : @"MockFlutterPlatformView"
3417 while (touchInteceptorView != nil &&
3419 touchInteceptorView = touchInteceptorView.superview;
3421 XCTAssertNotNil(touchInteceptorView);
3423 XCTAssert(touchInteceptorView.gestureRecognizers.count == 2);
3424 UIGestureRecognizer* delayingRecognizer = touchInteceptorView.gestureRecognizers[0];
3425 UIGestureRecognizer* forwardingRecognizer = touchInteceptorView.gestureRecognizers[1];
3432 XCTAssertEqual(touchInteceptorView.gestureRecognizers[0], delayingRecognizer);
3433 XCTAssertEqual(touchInteceptorView.gestureRecognizers[1], forwardingRecognizer);
3437 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForSimpleWebView {
3438 if (@available(iOS 26.0, *)) {
3439 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3441 flutter::TaskRunners runners(
self.name.UTF8String,
3442 GetDefaultTaskRunner(),
3443 GetDefaultTaskRunner(),
3444 GetDefaultTaskRunner(),
3445 GetDefaultTaskRunner());
3448 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3449 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3452 flutterPlatformViewsController,
3455 std::make_shared<fml::SyncSwitch>());
3459 [flutterPlatformViewsController
3465 [flutterPlatformViewsController
3468 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3475 while (touchInteceptorView != nil &&
3477 touchInteceptorView = touchInteceptorView.superview;
3479 XCTAssertNotNil(touchInteceptorView);
3493 root.gestureRecognizers = nil;
3494 for (UIView* subview in root.subviews) {
3495 [subview removeFromSuperview];
3499 [root addGestureRecognizer:normalRecognizer0];
3501 UIView* child1 = [[UIView alloc] init];
3502 [root addSubview:child1];
3504 [child1 addGestureRecognizer:normalRecognizer1];
3506 UIView* child2 = [[UIView alloc] init];
3507 [root addSubview:child2];
3509 [child2 addGestureRecognizer:normalRecognizer2];
3511 UIView* child2_1 = [[UIView alloc] init];
3512 [child2 addSubview:child2_1];
3514 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3516 UIView* child2_2 = [[UIView alloc] init];
3517 [child2 addSubview:child2_2];
3519 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3524 [root addGestureRecognizer:targetRecognizer0];
3528 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3532 NSArray* normalRecognizers = @[
3533 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3537 NSArray* targetRecognizers = @[ targetRecognizer0, targetRecognizer2_2 ];
3539 NSArray* expectedEmptyHistory = @[];
3540 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3543 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3546 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3552 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForMultipleWebViewInDifferentBranches {
3553 if (@available(iOS 26.0, *)) {
3554 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3556 flutter::TaskRunners runners(
self.name.UTF8String,
3557 GetDefaultTaskRunner(),
3558 GetDefaultTaskRunner(),
3559 GetDefaultTaskRunner(),
3560 GetDefaultTaskRunner());
3563 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3564 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3567 flutterPlatformViewsController,
3570 std::make_shared<fml::SyncSwitch>());
3574 [flutterPlatformViewsController
3576 withId:@"MockWrapperWebView"
3580 [flutterPlatformViewsController
3584 @"viewType" : @"MockWrapperWebView"
3592 while (touchInteceptorView != nil &&
3594 touchInteceptorView = touchInteceptorView.superview;
3596 XCTAssertNotNil(touchInteceptorView);
3614 for (UIView* subview in root.subviews) {
3615 [subview removeFromSuperview];
3619 [root addGestureRecognizer:normalRecognizer0];
3621 UIView* child1 = [[UIView alloc] init];
3622 [root addSubview:child1];
3624 [child1 addGestureRecognizer:normalRecognizer1];
3626 UIView* child2 = [[WKWebView alloc] init];
3627 child2.gestureRecognizers = nil;
3628 for (UIView* subview in child2.subviews) {
3629 [subview removeFromSuperview];
3631 [root addSubview:child2];
3633 [child2 addGestureRecognizer:normalRecognizer2];
3635 UIView* child2_1 = [[UIView alloc] init];
3636 [child2 addSubview:child2_1];
3638 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3640 UIView* child2_2 = [[UIView alloc] init];
3641 [child2 addSubview:child2_2];
3643 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3645 UIView* child3 = [[UIView alloc] init];
3646 [root addSubview:child3];
3648 [child3 addGestureRecognizer:normalRecognizer3];
3650 UIView* child3_1 = [[WKWebView alloc] init];
3651 child3_1.gestureRecognizers = nil;
3652 for (UIView* subview in child3_1.subviews) {
3653 [subview removeFromSuperview];
3655 [child3 addSubview:child3_1];
3657 [child3_1 addGestureRecognizer:normalRecognizer3_1];
3659 UIView* child3_1_1 = [[UIView alloc] init];
3660 [child3_1 addSubview:child3_1_1];
3662 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
3664 UIView* child3_1_2 = [[UIView alloc] init];
3665 [child3_1 addSubview:child3_1_2];
3667 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
3673 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3677 [child3_1_2 addGestureRecognizer:targetRecognizer3_1_2];
3681 NSArray* normalRecognizers = @[
3682 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3683 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
3684 normalRecognizer3_1_2
3686 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2 ];
3688 NSArray* expectedEmptyHistory = @[];
3689 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3692 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3696 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3702 testFlutterPlatformViewBlockGestureUnderEagerPolicyShouldDisableAndReEnableTouchEventsGestureRecognizerForNestedMultipleWebView {
3703 if (@available(iOS 26.0, *)) {
3704 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3706 flutter::TaskRunners runners(
self.name.UTF8String,
3707 GetDefaultTaskRunner(),
3708 GetDefaultTaskRunner(),
3709 GetDefaultTaskRunner(),
3710 GetDefaultTaskRunner());
3713 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3714 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3717 flutterPlatformViewsController,
3720 std::make_shared<fml::SyncSwitch>());
3724 [flutterPlatformViewsController
3730 [flutterPlatformViewsController
3733 arguments:@{@"id" : @2, @"viewType" : @"MockWebView"}]
3740 while (touchInteceptorView != nil &&
3742 touchInteceptorView = touchInteceptorView.superview;
3744 XCTAssertNotNil(touchInteceptorView);
3764 root.gestureRecognizers = nil;
3765 for (UIView* subview in root.subviews) {
3766 [subview removeFromSuperview];
3770 [root addGestureRecognizer:normalRecognizer0];
3772 UIView* child1 = [[UIView alloc] init];
3773 [root addSubview:child1];
3775 [child1 addGestureRecognizer:normalRecognizer1];
3777 UIView* child2 = [[UIView alloc] init];
3778 [root addSubview:child2];
3780 [child2 addGestureRecognizer:normalRecognizer2];
3782 UIView* child2_1 = [[UIView alloc] init];
3783 [child2 addSubview:child2_1];
3785 [child2_1 addGestureRecognizer:normalRecognizer2_1];
3787 UIView* child2_2 = [[UIView alloc] init];
3788 [child2 addSubview:child2_2];
3790 [child2_2 addGestureRecognizer:normalRecognizer2_2];
3792 UIView* child3 = [[UIView alloc] init];
3793 [root addSubview:child3];
3795 [child3 addGestureRecognizer:normalRecognizer3];
3797 UIView* child3_1 = [[WKWebView alloc] init];
3798 child3_1.gestureRecognizers = nil;
3799 for (UIView* subview in child3_1.subviews) {
3800 [subview removeFromSuperview];
3802 [child3 addSubview:child3_1];
3804 [child3_1 addGestureRecognizer:normalRecognizer3_1];
3806 UIView* child3_1_1 = [[UIView alloc] init];
3807 [child3_1 addSubview:child3_1_1];
3809 [child3_1_1 addGestureRecognizer:normalRecognizer3_1_1];
3811 UIView* child3_1_2 = [[UIView alloc] init];
3812 [child3_1 addSubview:child3_1_2];
3814 [child3_1_2 addGestureRecognizer:normalRecognizer3_1_2];
3816 UIView* child3_1_2_1 = [[UIView alloc] init];
3817 [child3_1_2 addSubview:child3_1_2_1];
3819 [child3_1_2_1 addGestureRecognizer:normalRecognizer3_1_2_1];
3821 UIView* child3_1_2_2 = [[UIView alloc] init];
3822 [child3_1_2 addSubview:child3_1_2_2];
3824 [child3_1_2_2 addGestureRecognizer:normalRecognizer3_1_2_2];
3830 [child2_2 addGestureRecognizer:targetRecognizer2_2];
3834 [child3_1_2_2 addGestureRecognizer:targetRecognizer3_1_2_2];
3838 NSArray* normalRecognizers = @[
3839 normalRecognizer0, normalRecognizer1, normalRecognizer2, normalRecognizer2_1,
3840 normalRecognizer2_2, normalRecognizer3, normalRecognizer3_1, normalRecognizer3_1_1,
3841 normalRecognizer3_1_2, normalRecognizer3_1_2_1, normalRecognizer3_1_2_2
3844 NSArray* targetRecognizers = @[ targetRecognizer2_2, targetRecognizer3_1_2_2 ];
3846 NSArray* expectedEmptyHistory = @[];
3847 NSArray* expectedToggledHistory = @[ @NO, @YES ];
3850 XCTAssertEqualObjects(recognizer.toggleHistory, expectedEmptyHistory);
3854 XCTAssertEqualObjects(recognizer.toggleHistory, expectedToggledHistory);
3859 - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashing {
3860 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3862 flutter::TaskRunners runners(
self.name.UTF8String,
3863 GetDefaultTaskRunner(),
3864 GetDefaultTaskRunner(),
3865 GetDefaultTaskRunner(),
3866 GetDefaultTaskRunner());
3869 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3870 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3873 flutterPlatformViewsController,
3876 std::make_shared<fml::SyncSwitch>());
3880 [flutterPlatformViewsController
3882 withId:@"MockFlutterPlatformView"
3886 [flutterPlatformViewsController
3890 @"viewType" : @"MockFlutterPlatformView"
3897 flutter::MutatorsStack stack;
3898 flutter::DlMatrix finalMatrix;
3900 auto embeddedViewParams_1 =
3901 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
3903 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3904 withParams:std::move(embeddedViewParams_1)];
3905 [flutterPlatformViewsController
3909 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
3910 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
3911 nullptr, framebuffer_info,
3912 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return false; },
3913 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3914 flutter::DlISize(800, 600));
3915 XCTAssertFalse([flutterPlatformViewsController
3916 submitFrame:std::move(mock_surface)
3917 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3919 auto embeddedViewParams_2 =
3920 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
3921 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3922 withParams:std::move(embeddedViewParams_2)];
3923 [flutterPlatformViewsController
3927 auto mock_surface_submit_true = std::make_unique<flutter::SurfaceFrame>(
3928 nullptr, framebuffer_info,
3929 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
3930 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
3931 flutter::DlISize(800, 600));
3932 XCTAssertTrue([flutterPlatformViewsController
3933 submitFrame:std::move(mock_surface_submit_true)
3934 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
3938 testFlutterPlatformViewControllerResetDeallocsPlatformViewWhenRootViewsNotBindedToFlutterView {
3939 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3941 flutter::TaskRunners runners(
self.name.UTF8String,
3942 GetDefaultTaskRunner(),
3943 GetDefaultTaskRunner(),
3944 GetDefaultTaskRunner(),
3945 GetDefaultTaskRunner());
3948 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
3949 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
3952 flutterPlatformViewsController,
3955 std::make_shared<fml::SyncSwitch>());
3957 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
3958 flutterPlatformViewsController.
flutterView = flutterView;
3962 [flutterPlatformViewsController
3964 withId:@"MockFlutterPlatformView"
3970 [flutterPlatformViewsController
3974 @"viewType" : @"MockFlutterPlatformView"
3978 flutter::MutatorsStack stack;
3979 flutter::DlMatrix finalMatrix;
3980 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
3981 finalMatrix, flutter::DlSize(300, 300), stack);
3982 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
3983 withParams:std::move(embeddedViewParams)];
3989 [flutterPlatformViewsController
reset];
3994 - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
3995 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
3997 flutter::TaskRunners runners(
self.name.UTF8String,
3998 GetDefaultTaskRunner(),
3999 GetDefaultTaskRunner(),
4000 GetDefaultTaskRunner(),
4001 GetDefaultTaskRunner());
4004 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4005 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4008 flutterPlatformViewsController,
4011 std::make_shared<fml::SyncSwitch>());
4013 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4014 flutterPlatformViewsController.
flutterView = flutterView;
4018 [flutterPlatformViewsController
4020 withId:@"MockFlutterPlatformView"
4025 [flutterPlatformViewsController
4029 @"viewType" : @"MockFlutterPlatformView"
4034 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4035 flutter::MutatorsStack stack;
4036 flutter::DlMatrix finalMatrix;
4037 auto embeddedViewParams1 =
4038 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4039 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4040 withParams:std::move(embeddedViewParams1)];
4041 [flutterPlatformViewsController
4048 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4051 auto embeddedViewParams2 =
4052 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4053 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4054 withParams:std::move(embeddedViewParams2)];
4055 [flutterPlatformViewsController
4063 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithDifferentViewHierarchy {
4064 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4066 flutter::TaskRunners runners(
self.name.UTF8String,
4067 GetDefaultTaskRunner(),
4068 GetDefaultTaskRunner(),
4069 GetDefaultTaskRunner(),
4070 GetDefaultTaskRunner());
4073 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4074 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4077 flutterPlatformViewsController,
4080 std::make_shared<fml::SyncSwitch>());
4082 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4083 flutterPlatformViewsController.
flutterView = flutterView;
4087 [flutterPlatformViewsController
4089 withId:@"MockFlutterPlatformView"
4093 [flutterPlatformViewsController
4097 @"viewType" : @"MockFlutterPlatformView"
4103 [flutterPlatformViewsController
4107 @"viewType" : @"MockFlutterPlatformView"
4112 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4113 flutter::MutatorsStack stack;
4114 flutter::DlMatrix finalMatrix;
4115 auto embeddedViewParams1 =
4116 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4117 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4118 withParams:std::move(embeddedViewParams1)];
4120 auto embeddedViewParams2 =
4121 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4122 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4123 withParams:std::move(embeddedViewParams2)];
4125 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4126 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4127 nullptr, framebuffer_info,
4128 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4129 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4130 flutter::DlISize(800, 600),
nullptr,
true);
4131 XCTAssertTrue([flutterPlatformViewsController
4132 submitFrame:std::move(mock_surface)
4133 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4136 UIView* clippingView1 = view1.superview.superview;
4137 UIView* clippingView2 = view2.superview.superview;
4138 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4139 [flutterView.subviews indexOfObject:clippingView2],
4140 @"The first clipping view should be added before the second clipping view.");
4143 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4145 embeddedViewParams2 =
4146 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4147 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4148 withParams:std::move(embeddedViewParams2)];
4150 embeddedViewParams1 =
4151 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4152 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4153 withParams:std::move(embeddedViewParams1)];
4155 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4156 nullptr, framebuffer_info,
4157 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4158 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4159 flutter::DlISize(800, 600),
nullptr,
true);
4160 XCTAssertTrue([flutterPlatformViewsController
4161 submitFrame:std::move(mock_surface)
4162 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4164 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] >
4165 [flutterView.subviews indexOfObject:clippingView2],
4166 @"The first clipping view should be added after the second clipping view.");
4170 testFlutterPlatformViewControllerSubmitFrameShouldOrderSubviewsCorrectlyWithSameViewHierarchy {
4171 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4173 flutter::TaskRunners runners(
self.name.UTF8String,
4174 GetDefaultTaskRunner(),
4175 GetDefaultTaskRunner(),
4176 GetDefaultTaskRunner(),
4177 GetDefaultTaskRunner());
4180 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4181 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4184 flutterPlatformViewsController,
4187 std::make_shared<fml::SyncSwitch>());
4189 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4190 flutterPlatformViewsController.
flutterView = flutterView;
4194 [flutterPlatformViewsController
4196 withId:@"MockFlutterPlatformView"
4200 [flutterPlatformViewsController
4204 @"viewType" : @"MockFlutterPlatformView"
4210 [flutterPlatformViewsController
4214 @"viewType" : @"MockFlutterPlatformView"
4219 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4220 flutter::MutatorsStack stack;
4221 flutter::DlMatrix finalMatrix;
4222 auto embeddedViewParams1 =
4223 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4224 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4225 withParams:std::move(embeddedViewParams1)];
4227 auto embeddedViewParams2 =
4228 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4229 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4230 withParams:std::move(embeddedViewParams2)];
4232 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4233 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4234 nullptr, framebuffer_info,
4235 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4236 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4237 flutter::DlISize(800, 600),
nullptr,
true);
4238 XCTAssertTrue([flutterPlatformViewsController
4239 submitFrame:std::move(mock_surface)
4240 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4243 UIView* clippingView1 = view1.superview.superview;
4244 UIView* clippingView2 = view2.superview.superview;
4245 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4246 [flutterView.subviews indexOfObject:clippingView2],
4247 @"The first clipping view should be added before the second clipping view.");
4250 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4252 embeddedViewParams1 =
4253 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4254 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4255 withParams:std::move(embeddedViewParams1)];
4257 embeddedViewParams2 =
4258 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
4259 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4260 withParams:std::move(embeddedViewParams2)];
4262 mock_surface = std::make_unique<flutter::SurfaceFrame>(
4263 nullptr, framebuffer_info,
4264 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4265 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4266 flutter::DlISize(800, 600),
nullptr,
true);
4267 XCTAssertTrue([flutterPlatformViewsController
4268 submitFrame:std::move(mock_surface)
4269 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4271 XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] <
4272 [flutterView.subviews indexOfObject:clippingView2],
4273 @"The first clipping view should be added before the second clipping view.");
4276 - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
4277 unsigned char pixel[4] = {0};
4279 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
4282 CGContextRef context =
4283 CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace,
4284 static_cast<uint32_t
>(kCGBitmapAlphaInfoMask) &
4285 static_cast<uint32_t
>(kCGImageAlphaPremultipliedLast));
4286 CGContextTranslateCTM(context, -point.x, -point.y);
4287 [view.layer renderInContext:context];
4289 CGContextRelease(context);
4290 CGColorSpaceRelease(colorSpace);
4295 - (void)testHasFirstResponderInViewHierarchySubtree_viewItselfBecomesFirstResponder {
4297 UIWindow* window = [[UIWindow alloc] init];
4298 UITextField* textField = [[UITextField alloc] init];
4299 [window addSubview:textField];
4301 [textField becomeFirstResponder];
4302 XCTAssertTrue(textField.isFirstResponder);
4303 XCTAssertTrue(textField.flt_hasFirstResponderInViewHierarchySubtree);
4304 [textField resignFirstResponder];
4305 XCTAssertFalse(textField.isFirstResponder);
4306 XCTAssertFalse(textField.flt_hasFirstResponderInViewHierarchySubtree);
4309 - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstResponder {
4311 UIWindow* window = [[UIWindow alloc] init];
4312 UIView* view = [[UIView alloc] init];
4313 UIView* childView = [[UIView alloc] init];
4314 UITextField* textField = [[UITextField alloc] init];
4315 [window addSubview:view];
4316 [view addSubview:childView];
4317 [childView addSubview:textField];
4319 [textField becomeFirstResponder];
4320 XCTAssertTrue(textField.isFirstResponder);
4321 XCTAssertTrue(view.flt_hasFirstResponderInViewHierarchySubtree);
4322 [textField resignFirstResponder];
4323 XCTAssertFalse(textField.isFirstResponder);
4324 XCTAssertFalse(view.flt_hasFirstResponderInViewHierarchySubtree);
4327 - (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle {
4333 CGRect newRect = CGRectMake(0, 0, 10, 10);
4337 NSSet* set1 = [NSSet setWithObjects:view1, view2, nil];
4338 NSSet* set2 = [NSSet setWithObjects:view3, view4, nil];
4339 XCTAssertEqualObjects(set1, set2);
4340 XCTAssertTrue(CGRectEqualToRect(view3.frame, newRect));
4341 XCTAssertTrue(CGRectEqualToRect(view4.frame, newRect));
4344 - (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity {
4349 XCTAssertNotEqual(view1, view3);
4350 XCTAssertNotEqual(view2, view3);
4353 - (void)testMaskViewsReleasedWhenPoolIsReleased {
4354 __weak UIView* weakView;
4359 XCTAssertNotNil(weakView);
4361 XCTAssertNil(weakView);
4364 - (void)testClipMaskViewIsReused {
4365 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4367 flutter::TaskRunners runners(
self.name.UTF8String,
4368 GetDefaultTaskRunner(),
4369 GetDefaultTaskRunner(),
4370 GetDefaultTaskRunner(),
4371 GetDefaultTaskRunner());
4374 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4375 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4378 flutterPlatformViewsController,
4381 std::make_shared<fml::SyncSwitch>());
4385 [flutterPlatformViewsController
4387 withId:@"MockFlutterPlatformView"
4391 [flutterPlatformViewsController
4395 @"viewType" : @"MockFlutterPlatformView"
4400 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4401 flutterPlatformViewsController.
flutterView = flutterView;
4403 flutter::MutatorsStack stack1;
4405 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4406 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4407 stack1.PushTransform(screenScaleMatrix);
4409 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4410 stack1.PushClipRect(rect);
4412 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4413 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4415 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4416 withParams:std::move(embeddedViewParams1)];
4417 [flutterPlatformViewsController
4422 UIView* maskView1 = childClippingView1.maskView;
4423 XCTAssertNotNil(maskView1);
4426 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(100, 100)];
4427 flutter::MutatorsStack stack2;
4428 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4429 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4430 auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
4431 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4432 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4433 withParams:std::move(embeddedViewParams3)];
4434 [flutterPlatformViewsController
4441 [flutterPlatformViewsController
4445 @"viewType" : @"MockFlutterPlatformView"
4449 auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
4450 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4451 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4452 withParams:std::move(embeddedViewParams4)];
4453 [flutterPlatformViewsController
4459 UIView* maskView2 = childClippingView2.maskView;
4460 XCTAssertEqual(maskView1, maskView2);
4461 XCTAssertNotNil(childClippingView2.maskView);
4462 XCTAssertNil(childClippingView1.maskView);
4465 - (void)testDifferentClipMaskViewIsUsedForEachView {
4466 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4468 flutter::TaskRunners runners(
self.name.UTF8String,
4469 GetDefaultTaskRunner(),
4470 GetDefaultTaskRunner(),
4471 GetDefaultTaskRunner(),
4472 GetDefaultTaskRunner());
4475 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4476 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4479 flutterPlatformViewsController,
4482 std::make_shared<fml::SyncSwitch>());
4486 [flutterPlatformViewsController
4488 withId:@"MockFlutterPlatformView"
4493 [flutterPlatformViewsController
4497 @"viewType" : @"MockFlutterPlatformView"
4503 [flutterPlatformViewsController
4507 @"viewType" : @"MockFlutterPlatformView"
4513 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4514 flutterPlatformViewsController.
flutterView = flutterView;
4516 flutter::MutatorsStack stack1;
4518 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4519 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4520 stack1.PushTransform(screenScaleMatrix);
4522 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4523 stack1.PushClipRect(rect);
4525 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4526 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4528 flutter::MutatorsStack stack2;
4529 stack2.PushClipRect(rect);
4530 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4531 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4533 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4534 withParams:std::move(embeddedViewParams1)];
4535 [flutterPlatformViewsController
4539 UIView* childClippingView1 = view1.superview.superview;
4541 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4542 withParams:std::move(embeddedViewParams2)];
4543 [flutterPlatformViewsController
4547 UIView* childClippingView2 = view2.superview.superview;
4548 UIView* maskView1 = childClippingView1.maskView;
4549 UIView* maskView2 = childClippingView2.maskView;
4550 XCTAssertNotEqual(maskView1, maskView2);
4553 - (void)testMaskViewUsesCAShapeLayerAsTheBackingLayer {
4554 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4556 flutter::TaskRunners runners(
self.name.UTF8String,
4557 GetDefaultTaskRunner(),
4558 GetDefaultTaskRunner(),
4559 GetDefaultTaskRunner(),
4560 GetDefaultTaskRunner());
4563 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4564 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4567 flutterPlatformViewsController,
4570 std::make_shared<fml::SyncSwitch>());
4574 [flutterPlatformViewsController
4576 withId:@"MockFlutterPlatformView"
4581 [flutterPlatformViewsController
4585 @"viewType" : @"MockFlutterPlatformView"
4590 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
4591 flutterPlatformViewsController.
flutterView = flutterView;
4593 flutter::MutatorsStack stack1;
4595 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4596 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4597 stack1.PushTransform(screenScaleMatrix);
4599 flutter::DlRect rect = flutter::DlRect::MakeXYWH(2, 2, 3, 3);
4600 stack1.PushClipRect(rect);
4602 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4603 screenScaleMatrix, flutter::DlSize(10, 10), stack1);
4605 flutter::MutatorsStack stack2;
4606 stack2.PushClipRect(rect);
4607 auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
4608 screenScaleMatrix, flutter::DlSize(10, 10), stack2);
4610 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4611 withParams:std::move(embeddedViewParams1)];
4612 [flutterPlatformViewsController
4618 UIView* maskView = childClippingView.maskView;
4619 XCTAssert([maskView.layer isKindOfClass:[CAShapeLayer
class]],
4620 @"Mask view must use CAShapeLayer as its backing layer.");
4628 - (BOOL)validateOneVisualEffectView:(UIView*)visualEffectView
4629 expectedFrame:(CGRect)frame
4630 inputRadius:(CGFloat)inputRadius {
4631 XCTAssertTrue(CGRectEqualToRect(visualEffectView.frame, frame));
4632 for (UIView* view in visualEffectView.subviews) {
4633 if (![NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
4636 XCTAssertEqual(view.layer.filters.count, 1u);
4637 NSObject* filter = view.layer.filters.firstObject;
4639 XCTAssertEqualObjects([filter valueForKey:
@"name"],
@"gaussianBlur");
4641 NSObject* inputRadiusInFilter = [filter valueForKey:@"inputRadius"];
4642 XCTAssertTrue([inputRadiusInFilter isKindOfClass:[NSNumber
class]] &&
4643 flutter::BlurRadiusEqualToBlurRadius(((NSNumber*)inputRadiusInFilter).floatValue,
4650 - (void)testDisposingViewInCompositionOrderDoNotCrash {
4651 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4653 flutter::TaskRunners runners(
self.name.UTF8String,
4654 GetDefaultTaskRunner(),
4655 GetDefaultTaskRunner(),
4656 GetDefaultTaskRunner(),
4657 GetDefaultTaskRunner());
4660 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4661 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4664 flutterPlatformViewsController,
4667 std::make_shared<fml::SyncSwitch>());
4669 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4670 flutterPlatformViewsController.
flutterView = flutterView;
4674 [flutterPlatformViewsController
4676 withId:@"MockFlutterPlatformView"
4681 [flutterPlatformViewsController
4685 @"viewType" : @"MockFlutterPlatformView"
4688 [flutterPlatformViewsController
4692 @"viewType" : @"MockFlutterPlatformView"
4699 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4700 flutter::MutatorsStack stack;
4701 flutter::DlMatrix finalMatrix;
4702 auto embeddedViewParams0 = std::make_unique<flutter::EmbeddedViewParams>(
4703 finalMatrix, flutter::DlSize(300, 300), stack);
4704 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
4705 withParams:std::move(embeddedViewParams0)];
4707 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4708 finalMatrix, flutter::DlSize(300, 300), stack);
4709 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4710 withParams:std::move(embeddedViewParams1)];
4714 XCTestExpectation* expectation = [
self expectationWithDescription:@"dispose call ended."];
4716 [expectation fulfill];
4719 [flutterPlatformViewsController
4722 [
self waitForExpectationsWithTimeout:30 handler:nil];
4724 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4725 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4726 nullptr, framebuffer_info,
4727 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4728 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4729 flutter::DlISize(800, 600),
nullptr,
4731 XCTAssertTrue([flutterPlatformViewsController
4732 submitFrame:std::move(mock_surface)
4733 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4737 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:0]);
4738 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4744 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
4745 flutter::MutatorsStack stack;
4746 flutter::DlMatrix finalMatrix;
4747 auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
4748 finalMatrix, flutter::DlSize(300, 300), stack);
4749 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
4750 withParams:std::move(embeddedViewParams1)];
4752 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4753 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4754 nullptr, framebuffer_info,
4755 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4756 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4757 flutter::DlISize(800, 600),
nullptr,
true);
4758 XCTAssertTrue([flutterPlatformViewsController
4759 submitFrame:std::move(mock_surface)
4760 withIosContext:std::make_shared<flutter::IOSContextNoop>()]);
4764 XCTAssertNil([flutterPlatformViewsController platformViewForId:0]);
4765 XCTAssertNotNil([flutterPlatformViewsController platformViewForId:1]);
4768 - (void)testOnlyPlatformViewsAreRemovedWhenReset {
4769 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4771 flutter::TaskRunners runners(
self.name.UTF8String,
4772 GetDefaultTaskRunner(),
4773 GetDefaultTaskRunner(),
4774 GetDefaultTaskRunner(),
4775 GetDefaultTaskRunner());
4778 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4779 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4782 flutterPlatformViewsController,
4785 std::make_shared<fml::SyncSwitch>());
4789 [flutterPlatformViewsController
4791 withId:@"MockFlutterPlatformView"
4795 [flutterPlatformViewsController
4799 @"viewType" : @"MockFlutterPlatformView"
4802 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4803 flutterPlatformViewsController.
flutterView = flutterView;
4805 flutter::MutatorsStack stack;
4807 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4808 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4809 stack.PushTransform(screenScaleMatrix);
4811 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4812 stack.PushTransform(translateMatrix);
4813 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4815 auto embeddedViewParams =
4816 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4818 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4819 withParams:std::move(embeddedViewParams)];
4821 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4822 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4823 nullptr, framebuffer_info,
4824 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4825 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4826 flutter::DlISize(800, 600),
nullptr,
true);
4827 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4828 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4830 UIView* someView = [[UIView alloc] init];
4831 [flutterView addSubview:someView];
4833 [flutterPlatformViewsController
reset];
4834 XCTAssertEqual(flutterView.subviews.count, 1u);
4835 XCTAssertEqual(flutterView.subviews.firstObject, someView);
4838 - (void)testResetClearsPreviousCompositionOrder {
4839 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4841 flutter::TaskRunners runners(
self.name.UTF8String,
4842 GetDefaultTaskRunner(),
4843 GetDefaultTaskRunner(),
4844 GetDefaultTaskRunner(),
4845 GetDefaultTaskRunner());
4848 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4849 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4852 flutterPlatformViewsController,
4855 std::make_shared<fml::SyncSwitch>());
4859 [flutterPlatformViewsController
4861 withId:@"MockFlutterPlatformView"
4865 [flutterPlatformViewsController
4869 @"viewType" : @"MockFlutterPlatformView"
4872 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4873 flutterPlatformViewsController.
flutterView = flutterView;
4875 flutter::MutatorsStack stack;
4877 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4878 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4879 stack.PushTransform(screenScaleMatrix);
4881 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4882 stack.PushTransform(translateMatrix);
4883 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4885 auto embeddedViewParams =
4886 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4888 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4889 withParams:std::move(embeddedViewParams)];
4891 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4892 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4893 nullptr, framebuffer_info,
4894 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4895 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4896 flutter::DlISize(800, 600),
nullptr,
true);
4897 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4898 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4904 [flutterPlatformViewsController
reset];
4910 - (void)testNilPlatformViewDoesntCrash {
4911 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
4913 flutter::TaskRunners runners(
self.name.UTF8String,
4914 GetDefaultTaskRunner(),
4915 GetDefaultTaskRunner(),
4916 GetDefaultTaskRunner(),
4917 GetDefaultTaskRunner());
4920 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
4921 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
4924 flutterPlatformViewsController,
4927 std::make_shared<fml::SyncSwitch>());
4931 [flutterPlatformViewsController
4933 withId:@"MockFlutterPlatformView"
4937 [flutterPlatformViewsController
4941 @"viewType" : @"MockFlutterPlatformView"
4944 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
4945 flutterPlatformViewsController.
flutterView = flutterView;
4948 flutter::MutatorsStack stack;
4950 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
4951 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
4952 stack.PushTransform(screenScaleMatrix);
4954 flutter::DlMatrix translateMatrix = flutter::DlMatrix::MakeTranslation({100, 100});
4955 stack.PushTransform(translateMatrix);
4956 flutter::DlMatrix finalMatrix = screenScaleMatrix * translateMatrix;
4958 auto embeddedViewParams =
4959 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
4961 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
4962 withParams:std::move(embeddedViewParams)];
4964 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
4965 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
4966 nullptr, framebuffer_info,
4967 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
4968 [](
const flutter::SurfaceFrame& surface_frame) {
return true; },
4969 flutter::DlISize(800, 600),
nullptr,
true);
4970 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
4971 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
4973 XCTAssertEqual(flutterView.subviews.count, 1u);
4976 - (void)testFlutterTouchInterceptingViewLinksToAccessibilityContainer {
4978 NSObject* container = [[NSObject alloc] init];
4979 [touchInteceptorView setFlutterAccessibilityContainer:container];
4980 XCTAssertEqualObjects([touchInteceptorView accessibilityContainer], container);
4983 - (void)testLayerPool {
4987 XCTAssertTrue(
engine.platformView !=
nullptr);
4988 auto ios_context =
engine.platformView->GetIosContext();
4993 pool.
CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
4994 XCTAssertEqual(pool.size(), 1u);
4995 pool.CreateLayer(ios_context, MTLPixelFormatBGRA8Unorm);
4996 XCTAssertEqual(pool.size(), 2u);
4999 pool.RecycleLayers();
5000 XCTAssertEqual(pool.size(), 2u);
5003 auto unused_layers = pool.RemoveUnusedLayers();
5004 XCTAssertEqual(unused_layers.size(), 2u);
5005 XCTAssertEqual(pool.size(), 1u);
5008 - (void)testFlutterPlatformViewControllerSubmitFramePreservingFrameDamage {
5009 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5011 flutter::TaskRunners runners(
self.name.UTF8String,
5012 GetDefaultTaskRunner(),
5013 GetDefaultTaskRunner(),
5014 GetDefaultTaskRunner(),
5015 GetDefaultTaskRunner());
5018 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5019 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5022 flutterPlatformViewsController,
5025 std::make_shared<fml::SyncSwitch>());
5027 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
5028 flutterPlatformViewsController.
flutterView = flutterView;
5032 [flutterPlatformViewsController
5034 withId:@"MockFlutterPlatformView"
5038 [flutterPlatformViewsController
5042 @"viewType" : @"MockFlutterPlatformView"
5047 [flutterPlatformViewsController
5051 @"viewType" : @"MockFlutterPlatformView"
5055 [flutterPlatformViewsController beginFrameWithSize:flutter::DlISize(300, 300)];
5056 flutter::MutatorsStack stack;
5057 flutter::DlMatrix finalMatrix;
5058 auto embeddedViewParams1 =
5059 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(300, 300), stack);
5060 [flutterPlatformViewsController prerollCompositeEmbeddedView:0
5061 withParams:std::move(embeddedViewParams1)];
5063 auto embeddedViewParams2 =
5064 std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, flutter::DlSize(500, 500), stack);
5065 [flutterPlatformViewsController prerollCompositeEmbeddedView:1
5066 withParams:std::move(embeddedViewParams2)];
5068 flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
5069 std::optional<flutter::SurfaceFrame::SubmitInfo> submit_info;
5070 auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
5071 nullptr, framebuffer_info,
5072 [](
const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) {
return true; },
5073 [&](
const flutter::SurfaceFrame& surface_frame) {
5074 submit_info = surface_frame.submit_info();
5077 flutter::DlISize(800, 600),
nullptr,
5079 mock_surface->set_submit_info({
5080 .frame_damage = flutter::DlIRect::MakeWH(800, 600),
5081 .buffer_damage = flutter::DlIRect::MakeWH(400, 600),
5084 [flutterPlatformViewsController submitFrame:std::move(mock_surface)
5085 withIosContext:std::make_shared<flutter::IOSContextNoop>()];
5087 XCTAssertTrue(submit_info.has_value());
5088 XCTAssertEqual(*submit_info->frame_damage, flutter::DlIRect::MakeWH(800, 600));
5089 XCTAssertEqual(*submit_info->buffer_damage, flutter::DlIRect::MakeWH(400, 600));
5092 - (void)testClipSuperellipse {
5093 flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
5095 flutter::TaskRunners runners(
self.name.UTF8String,
5096 GetDefaultTaskRunner(),
5097 GetDefaultTaskRunner(),
5098 GetDefaultTaskRunner(),
5099 GetDefaultTaskRunner());
5102 flutterPlatformViewsController.
taskRunner = GetDefaultTaskRunner();
5103 auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
5106 flutterPlatformViewsController,
5109 std::make_shared<fml::SyncSwitch>());
5113 [flutterPlatformViewsController
5115 withId:@"MockFlutterPlatformView"
5119 [flutterPlatformViewsController
5123 @"viewType" : @"MockFlutterPlatformView"
5129 UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
5130 flutterPlatformViewsController.
flutterView = flutterView;
5132 flutter::MutatorsStack stack;
5134 flutter::DlScalar screenScale = [UIScreen mainScreen].scale;
5135 flutter::DlMatrix screenScaleMatrix = flutter::DlMatrix::MakeScale({screenScale, screenScale, 1});
5136 stack.PushTransform(screenScaleMatrix);
5138 flutter::DlRect rect = flutter::DlRect::MakeXYWH(3, 3, 5, 5);
5139 stack.PushClipRSE(flutter::DlRoundSuperellipse::MakeOval(rect));
5141 auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(
5142 screenScaleMatrix, flutter::DlSize(10, 10), stack);
5144 [flutterPlatformViewsController prerollCompositeEmbeddedView:2
5145 withParams:std::move(embeddedViewParams)];
5146 [flutterPlatformViewsController
5153 [flutterView addSubview:childClippingView];
5155 [flutterView setNeedsLayout];
5156 [flutterView layoutIfNeeded];
5158 CGPoint corners[] = {CGPointMake(rect.GetLeft(), rect.GetTop()),
5159 CGPointMake(rect.GetRight(), rect.GetTop()),
5160 CGPointMake(rect.GetLeft(), rect.GetBottom()),
5161 CGPointMake(rect.GetRight(), rect.GetBottom())};
5162 for (
auto point : corners) {
5163 int alpha = [
self alphaOfPoint:point onView:flutterView];
5164 XCTAssertNotEqual(alpha, 255);
5167 CGPointMake(rect.GetLeft() + rect.GetWidth() / 2, rect.GetTop() + rect.GetHeight() / 2);
5168 int alpha = [
self alphaOfPoint:center onView:flutterView];
5169 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)